Babylon JS Day 4

Today I completed the final two chapters of the Babylon JS Getting Started guide. These chapters focused mostly on lighting and cameras, but also briefly touched on GUI. Today’s interesting items are

  • Babylon JS has all the common 3D lighting types that I would expect. It has point, directional, spot, and hemispheric (ambient) lights.
  • Hemispheric lights don’t cast shadows, so for most scenes where I want shadows, I’ll need to add a directional light.
  • Adding shadows is a bit more involved than other platforms I’ve worked in. In addition to adding a light source that can cast shadows, I’ll need to add a `ShadowGenerator` to the scene. Then I need to add meshes that can cast shadows to the generater via the `addShadowCaster` method. Objects that need to receive shadows need to have the `receiveShadows` property flag set to true.
  • Babylon JS has several camera types. I’ve been using the `ArcRotateCamera` for most of the demo scenes so far. Interestingly, this camera can be attached to an object as a child to create a basic third-person camera view.
  • There is also a handy camera called `FollowCamera` that does what it says on the tin. Instead of attaching the camera to an object, I can just pass it the name of a mesh to track. This is useful when I want to have a camera track several objects over time in a scene.

This concludes my tour of the basics of Babylon JS. At this point I have a better idea of what Babylon JS has to offer and I’m started to get a feel for how it implements common features, how the API is structured. Tomorrow I’m going to dive into my first “project day” where I’ll try to build something (or several things) with what I’ve learned this week.

Babylon JS Day 3

Today I covered chapters five and six of the Babylon JS Getting Started guide. These chapter gave me a quick tour around some of the environmental features of Babylon JS. Notable items include

  • Ground planes/objects can be created with grayscale heightmaps. I’ve done this in Unity a few times. Nice to know this is available to me in Babylon.
  • Building skyboxes from images seems like sort of a nuisance. It’s good to know how to do this but most of the projects I want to build will use simple color or gradient skyboxes.
  • Babylon JS supports using sprites in 3D scenes as a type of billboard object. These will always face the camera. While this looks great in 3D scenes on desktop or mobile, these always look bad to me when I see them in VR.
  • Babylon JS has a nifty particle system. I could easily get lost with a feature like this and spend a great deal of time working on nothing but particles. Perhaps I’ll make one of my Friday Projects based around particles…
  • Bonus: I learned about another advanced modeling method called CreateLathe. You pass it an array of Vector3 points (along the same z plane) and it will create a 3D object. Super cool! I’ve used stuff like this in Blender before but to see this happen with just a few lines of JavaScript blew my mind.

Babylon JS Day 2

Today I worked through chapters three and four of the Babylon JS Getting Started guide. After working in Unity for a couple of years, most of these concepts are not new to me, just the way that Babylon JS implements them. Some things that stood out as interesting to me are

  • MeshBuilder has a method called ExtrudePolygon that can be used for complex extrusions. I wonder what other methods are available… While I can create some basic models in Blender, I have trouble using tools like that because they require the constant use of a pointing device. I will happily create models via code when I can.
  • Lots of information on how Babylon JS handles animations. Animations can be imported along with models and used in a scene, but I can also code some animations directly in Babylon JS. There are a handful of interesting playgrounds with sample code to check out.
  • There is a handy method called movePOV that will move an object using it’s forward vector. When using this I don’t have to calculate differences in vectors based on orientation of the object I’m moving. I can just pass a Vector3 that indicates the movement from the perspective of the object.
  • Chapter 4 was a brief introduction to collisions. It explained how to test for collision between two objects. I need to learn more about the default bounding boxes and if I can customize these shapes.

A Month of Babylon JS

Throughout the month of March, I’m going to learn everything I can about Babylon JS. Over the last year I’ve spent a bit of time with A-Frame, Three JS, and Babylon JS. I explained my reasoning for settling on Babylon JS in the most recent episodes of Project Update.

I have a history of spending too much time on courses and educational content, and not enough time building something with the tools I’m learning. This month I’m going to try to break that cycle by planning how I work on this project.

  1. I’m going to stop work an hour early each day (Monday through Thursday) to spend time working through the Babylon JS Getting Started guide and documentation.
  2. I’m going to take each Friday in March as a day to spend building small projects, with an emphasis on what I’ve learned over the previous days.

My hope is that this approach will place some limits on the project while giving me plenty of time to spend on it. While this is clearly in the “side project” column of work, I still consider this actual work and will treat it as such. I’ll be tracking my time, taking lots of notes, and reporting my progress during Project Update recordings with Dave.

One of my goals for this project is to learn to think in the way that Babylon JS and other similar JavaScript frameworks want me to think. These environments all approach problems in ways than I’m not accustomed to. I’m just not used to thinking in in the JS way yet. With a background in FileMaker development, lots of work in PHP, Swift, and C#–I’m used to solving problems in ways that don’t always make sense in the JS context.

I got started on this project yesterday, March 1, 2021, with the Babylon JS Getting Started Guide. I worked my way through chapters one and two. While most of this was just a refresher of things I already knew, I did pick up a few things.

  • I don’t always need to pass a reference to a scene when creating an object. When I leave this null the value will default to the current scene.
  • I can save/export Babylon JS scenes to a .babylon file format that can be viewed or imported elsewhere.
  • I can import entire scenes or portions of scenes from these saved files. This seems like an interesting way of making something like Prefabs in Unity.
  • Babylon JS has some interesting ways of making copies and instances of objects. I want to learn more about instances and what they inherit from their base objects.

End of Retrospective Timelines (and app development)

As of today, I’m giving up on my half-baked plans to make consumer software. I just took Retrospective Timelines off of the App Store and I don’t plan on renewing my Apple developer account. There are a number of reasons I’m making this decision. I’ll try to list a few here.

While I enjoyed the process of developing the app, it’s become clear to me that I will *never* actually do any of the marketing steps needed to promote a consumer product. I’ve made grand plans many times and at the end of the day I just refuse to do the work.

From the coding side, working with Apple APIs has been the most frustrating experience of my career. SwiftUI is a mess and I want nothing to do with UIKit. Core Data and CloudKit are needlessly complex for very little gain over using something else.

From a business aspect, it just doesn’t make sense for me to continue spending time on app ideas and other consumer products (games, VR apps, etc.). It is clear to me that my skills as a software and business consultant are far more valuable than any app I’ll ever make.

I may end up changing my mind someday when I have some hairbrained idea for an app (especially for AR headsets) but for now my time and energy are better spent working on projects that have a clear payoff, and a clear end.

On a personal note, my RSI is getting worse and worse. I can’t afford to do any “hobby” development like I used to. There is a limited time I can spend using a computer and I must spend that time on productive work.

Summer Planning for Retrospective Timelines

I am beginning the planning process for Retrospective Timelines 2.0. Below I listed some of the areas that I want to focus on this summer. My hope is that the latest round of updates to SwiftUI, iOS 14, and iPadOS 14 will enable me to make significant improvements to the app. I have only just started to learn about the new features, so I do not know which of these items are possible yet.  

Modal Windows / Views 

The current version of Retrospective Timelines uses sort of a hacky solution to be able to present the data entry screens in a modal mode. There were some weird bugs with SwiftUI sheets last year where onDismiss was not always called. Are these issues solved? Can I now present modal views where the user must use the Cancel and Done buttons to close the view? 

Alternatively, can I rethink my design entirely to omit this type of data flow? Currently I am using modal views to validate the data before the user saves the record. Perhaps I should rethink this process and save each change that the user makes on the data entry screen. 

Toolbars 

The current implementation of toolbars is a real mess. I found a lot of issues with buttons when placed in a navigation view (some of them having to do with opening and closing modals). Can I use the new toolbar features in SwiftUI 2 to replace all this stuff?  

Navigation Structure and List Views 

The current navigational structure of the app is less than ideal. It looks fine on an iPhone but on an iPad it is really quite bad. I would love to make a three-column interface for iPadOS. I think I might be able to use the new Sidebar APIs to accomplish this. 

I also want to use a new feature in List to group my main list view. The new child keypath feature could let me place all three top level elements in one list. Those are Reports, Active Timelines, and Archived Timelines. 

Something that annoyed me on iPad was the lack of a readable width setting for list views. Has this been added? It might not be as important if I can get the three-column interface working. 

Other stuff

  • Data Entry: TextField in SwiftUI 1.0 is bad. I mean really really bad. It has so many issues that I think nobody should be using it in a shipping app. Because of all of the bugs and missing features I ended up rewriting all my data entries screens in UIKit. I would love to write these in SwiftUI if I can. 
  • Grids: SwiftUI 2 has a new grid feature. I think I can use this to replace my hacky solution for the color and icon pickers for timelines.  
  • Accent Color: I did this the hard way last year. I am going to use this new method for the next version of my app. 
  • SwiftUI now has a feature for opening URLs. I can remove my hack for this as well. 
  • Core Data: I would love to learn some new ways to work with Core Data and CloudKit in SwiftUI. The approach I took last year has a lot of limitations and issues. 

As you can probably tell, I have no idea yet what is possible and what is not. I have a lot of work cut out for me over the next few weeks. I’m going to start a new branch in my repo and dive in. I’m also going to try a whole new code path in my project. Rather than try to update my current views, I’m going to start with a new top level view and work my way through reimplementing each core feature of the app, with an emphasis on learning the new APIs along the way.

Retrospective Timelines 1.0.4

A new version of Retrospective Timelines is rolling out now. This version adds a handful of new features

  • New Settings to control formatting for dates and durations. Select these settings to apply them across the app.
  • Redesigned share view with new formatting options for dates and durations.
  • Events can now have text notes. Enter notes on the Event Edit screen. Notes are viewable on Events Detail.

There is also a new bonus feature on the Event Detail screen. Now that the app supports multiple format types for dates and durations, I decided it would be awesome to switch between these with a simple tap. When you are viewing an Event on the Event Detail screen, just tap a date or duration to cycle through the available format options. Doing so won’t effect the defaults that you can set on the settings screen.

Data Entry with SwiftUI and UIKit

Version 1.0 of Retrospective Timelines was written completely in SwiftUI and while I’m excited to keep working in SwiftUI, there were some issues and limitations that it imposed on my app.

You can’t really talk about SwiftUI without someone pointing out that it’s not “ready” to be used in production yet. I mostly disagree with that sentiment, but when it comes to data entry forms it rings true. Many of the common UI controls in SwiftUI have the most basic implementation possible, often with little to no ability to customize them.

SwiftUI TextField for example.

  • No way to dismiss the keyboard (you can press Return, but a lot of users don’t think to try that)
  • Text selection in the field is really flakey.
  • No SwiftUI equivalent of TextView, so multi-line text is not possible
  • Speech to Text fails. I’ve tried this on every device I have and it fails 100% of the time. It will insert the first character from the first word you speak, then quit listening. I reported this bug months ago.

These issues and limitations were reflecting poorly on the app and giving my users the wrong impression so I decided to do something about it.

My first attempt was to wrap the UIKit controls in SwiftUI wrappers, but I had little success. I cobbled together a sort-of-working version of UITextField, but it was buggy and unreliable. It was also super slow. Rather than keep spending time on it, I decided to just write the entire screens in UIKit.

In Retrospective Timelines all data entry is done in a modal view. There are only two data entry forms and a limited number of ways to open them. I had already disregarded SwiftUIs sheet presentation due to its limitations and instead was using an environmental variable to get the hosting View Controller to use for presentation. All had to do was change the View Controller that I was presenting from the SwiftUI hosting controller I was showing, to a new UIKt version.

I don’t know a ton about UIKit, so it took me a couple of days to make these forms. I used a storyboard for the view controllers and some XIBs for small elements like collection and table view cells. The forms are basically static UITableViewController objects with a ton of customization. Setting these up and accounting for all of the edge cases was a lot more work than the same thing in SwiftUI. I found myself missing the way SwiftUI handle the state of data.

The end result turned to better than I thought possible, so I can’t really complain. Not only did I work around the limitations of the SwiftUI controls, I also ended up with a far better version of the Color and Image pickers for Timelines.

Retrospective Timelines 1.0.3

A new update is rolling out now with improvements to the data entry screens for Timelines and Events. These screens have been completely rewritten to support user interface features common to iOS apps.

Time Tracking in 2020

While working on my goals and my annual theme for 2020, I decided that I’m going to give time tracking another try. When I was working full time as a consultant I used to track all of my time because the companies I worked for mostly billed by the hour. When I started Radical Application Development in 2015 I knew that I didn’t want to bill by the hour. Why? That’s for another post some time… or you can just read this to find out a lot more than I will ever explain.

Even without relying on billable time, I have at certain points used time tracking in my business. I find it helpful to set goals for myself such as:

  • “Work at least X hours on Project Y per day”
  • “Spend no more than X hours on product Z”

I’ve built my own time tracking apps in FileMaker and in 2016 I attempted to build one in Swift (it went badly…) I’ve also used a number of third-party apps and service. The problem is that I hate every single one of them, and all for the same reasons. The time part of time tracking. When I say I want to track my time, what I really mean is that I want to track the duration or amount of time I spent on an activity. I don’t want to track start and end times, I don’t want to punch a clock, and I really dislike the idea of having timers running while I work.

What I really want is a place where I can list out all of the activities that I would track time against, and then a super simple interface to enter a block of time for an activity and day. On Sunday I decided take another attempt at building my own time tracking app in Swift. This time I’m using SwiftUI and Core Data, along with all of the lessons that I learned building Retrospective Timelines. I talked through some of my ideas with my friend Dave and wrote out a short punch list. I decided to build something as fast as possible so I could start using it on Jan 1.

Yesterday I worked out some of the details around the schema. I setup Core Data CloudKit so I can use the app on multiple devices. I make a few simple placeholder views and started working on data entry. Today I kept working on the UI and got it far enough along that I can use it to log time against a list of activities. It’s really really basic, but it will serve my needs for at least a few weeks. I can work on adding small features to it in my spare time.

My time tracking app as of 2019.12.31

I have no idea if I’m going to try to turn this into a product or not. I think I’d like so, but I’m not sure how many other people think about time tracking in the same way that I do, without the need to enter clock time or use timers.

If this is something you are interested in please get in touch. Use the contact form or reach out to me on Twitter.

1 2 3 4 5 6