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:
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?