Discussion: dynamic external symbol loading, and why not-having-it is such a profound problem


#1

I’m about to email Zap support about this, as it’s a critical issue for us: but I thought it worth posting here for discussion. Grab a coffee and a comfy seat, though, this is going to be long.

I’m at the point in my AR research where I have to pick a provider, and Zap is ticking all the boxes for us, with one huge caveat. It sounds trivial and esoteric, niche even, but it has a profound effect on workflow and scalability. It’s the fact we can’t load external symbols dynamically.

(anywhere I write “symbol”, read it as “subsymbol” if that helps - but they’re the same thing)

Workflow wise this means:

  • we can’t modularise our development properly. If you want to use a common symbol across multiple experiences, it has to be copied in. It can’t just be referenced. So any changes to that symbol then have to be manually copied into every experience, relinked, the old one removed.
  • we can’t preview symbols without previewing the whole project they’re in. When tweaking a small symbol within a big project, that makes the development iteration loop incredibly wasteful, time-wise. Every little tweak requires the whole project to be reuploaded.
  • we can’t use traditional version control for symbols. If, say, we decide to change how our universal “call-to-action” button in all our experiences works, there’s no way for us to know all our experiences have the latest version without opening each one up separately and checking it. There’s no way to roll back just a symbol.
  • memory footprint and payload size are larger than they need to be. If we create a reusable element (say, a lens-flare generator), and we want to use that within a variety of different symbols, it has to be a copy each time. Any assets we use within it end up being copies. It’s all copies.

Project scale is limited:

  • all the logic and animation in an experience has to be contained in one single monolithic project. If you want to make a 5 minute AR music video experience, say, it all has to be squished into that single project. If you want to make a rich game experience, every single level, every bit of gameplay logic from start to end, has to be in that single project. If you want to let the user make choices within an experience, every possible outcome has to be built into that single project.

I know what you’re thinking, honourable reader: hey, @howiemnet, there are workarounds that can ameliorate some of this: you can stream in images / audio / video / meshes, and you can deep link between experiences, and if you want to isolate a symbol to work on, there’s nothing to stop you exporting a copy, opening that up on its own etc, then re-integrating it into all your projects again. But its a usability nightmare. Deep linking between experiences is horribly clunky and about as un-seamless as you can imagine: you certainly can’t do it within an audio track, and you can’t carry any sort of tracking state over.

Just to lighten the mood slightly, here’s a drawing of a cat:

37

OK.

I cannot imagine that this isn’t on Zap’s roadmap. It just must be. And I can understand why it wasn’t a day one feature: it’s relatively advanced, and it requires us devs to know what we’re doing. But we’ve been doing this kind of dynamic subsymbol stuff since the days of Macromedia Flash, so it’s not a new concept even in this world of interactive media. I absolutely don’t buy any argument along the lines of “but it would add complexity for our users”. There’s nothing about this that would make life harder for users who don’t want or need to use it.

It wouldn’t even need a new function. A Zap project is a symbol, so you should be able publish your symbol just like any other project, and load and attach it just like you can with a mesh:

let mySymbol = Z.Object().type('https://zpr.link/z/abcdefghijk'); // my "subsymbol" / project
mySymbol.on('ready',(){
    symbol.nodes.Group.push(mySymbol);
    console.log('symbol loaded! Go wiid!');
    mySymbol.nodes.myCodeNode.initialiseAllTheThings(); // or whatevs
    mySymbol.controllers.display.elements.t_reveal_animation.play(); // etc
}

I’m oversimplifying perhaps. But it doesn’t need to be hard or complex, at least on the surface.

There are quite possibly some hard problems Zap would need to look at, some warnings and caveats they’d need to wrap an implementation of this with; lack of garbage collection (reclaiming memory from unloaded instances) being the prime one I can think of. But again, we’re grown ups, so as long as we’re aware of these issues, it’d be up to us devs to deal with it, to test, to workaround.

We’re definitely sticking with Zap for our first projects: the WebAR implementation is fantastic, and Zap Studio is (despite its quirks) an incredibly effective and efficient IDE. But this single thing - dynamic symbol loading - is the key determining factor for us in whether we have to keep exploring other options for larger, longer, richer experiences, and for a more coherent overall AR strategy.

If you’re still reading this, what are your thoughts?


#2

Zapworks Studio does have dynamic symbol loading, check this out. You can’t preview a subsymbol though, and I agree it would be great if it was possible.


#3

But that symbol, albeit dynamically loaded, has to have been imported into the main project, right?

'Cos if you can load it like this but from a URL then I’ll have to eat my words and take down my cat drawing in embarrassment

EDIT: I’ve added “external” to the subject and body to make this more clear


#4

Oh, yes. The subsymbol must already be in the project so that you can instantiate it dynamically. I don’t think it’s possible to download a symbol first and then instantiate it. But maybe it is!

Zapworks Studio unfortunately is quite limited when it comes to doing dynamic stuff. I’d suggest you take a look into UniversalAR. Use it with Unity or PlayCanvas for example. Then I am 100% sure you can do everything you want.

However, I’d like Zapworks Studio to get more love as well. It is easier to use and more robust when it comes to static stuff.


#5

It would definitely help. I reuse symbols a lot and have to check them before I add them. I have some that do this and some that do that of the same symbol.

Steve


#6

@stevesanerd: yes. This. Exactly this.

There are plenty of times you do want to customise a symbol for a particular situation, so being able to import (ie copy) a symbol into a project is essential. But more often than not I just want to be sure I’ve got the latest version of a symbol.

It’s that flippin’ particle generator of mine that’s going to be the biggest issue; I’ve used it in about a dozen different places in my current project. Same symbol each time, but because it appears within different subsymbols, there are multiple copies of it. I need to optimise it, tighten up the code; but when I do it’s going to be a pain in the bum having to remember all the places it needs swapping out with the new version.

It oughta be its own standalone publishable project. Won’t do anything on its own - it just sits there waiting to be told what and when to emit - but then other projects could call on it when they need it, and if I tweak or optimise it, all I’d have to do it republish that single “h_particle_system” project. No need to even open, let alone re-publish the projects that use it; they’d just call up the latest one.

Mad how emotional I get over abstract little features like this, but I just want an easy life :wink:


#7

Another solution that would alleviate the problem are global symbols.