Project Brief:
Make something cool with node.js, express, websockets, and a database.
Ideation:
I really really really suck at fullstack and backend, dealing with data, security, timing, efficiency deployment etc. I'm very much frontend visuals and graphics oriented in my programming. When trying to think about ideas for this project I literally hopped on a call with my friend getting him to explain what backend truly encapsulated and use cases for express and node.js. I literally needed it spelled out so that I could start coming up with project ideas that would actually use express and a database. My first idea was far too lofty as I didn't realize how soon the second project was due, I toying around with a conceptual immersive web installation based on the end of time. Predicated on the assumption and belief that one of the core purposes/affordances of art is to create and communicate emotional connections. At the end of time users would no longer be able to communicate via speech anymore, instead all user input would be programmatically transformed into abstract visualizations and soundscapes, users would be asked to experiment and tweak their final messages to their likings before sending them off to the void to be viewed by others. It's an idea that I'm still interested in exploring but needs refinement both conceptually and in the logistical planning.
I considered revisiting and old sketch I had made in undergrad where I controlled a 3D model of a plane via my phone, it was a socket.io video game that I never finished developing but used sockets, node and express!...It would have been a cop out of sorts and I have very little interest in video game design at the moment. In my previous project I had virtual buttons laid out on my phone client page and essentially just created a remote virtual keyboard. I toyed with the idea of building on that concept instead of re-using it and exploring phone orientation for controlling 3D avatars. Being able to turn your phone like a wheel to steer your avatar in 3D space etc, an exploration of adding physicality and materiality back to the digital world. I dreamed of recreating Mozilla's VRpainter in three.js with a phone controlling a brush in 3D space! Expectedly, I was growing ever closer to becoming Icarus and trying to fly towards the sun. Luckily before I could get destroyed trying to take on this massive project, it turns out the three.js orientation controls are so rarely used and poorly documented that I never got off the ground! Phew disaster averted.
With 48 hours left and literally no project at hand I revisited a variation of my first project idea, a virtual home containing all my past failures and half finished ideas. My initial idea allowed users to explore the space and click around to download fragments of code and projects for inspiration as well as upload their own unfinished sketches for the public to see and download. A collaborative catharsis that none of us are perfect and get it right the first time, a shared experience of being content in the process. The webpage would check for updates in the server and database and programmatically fill the space with clickable 3D objects based on new submissions. In lieu of the massive security and efficiency risks of having an open datastore for people to upload whatever they want without moderation and potentially exposing users to malicious or unwanted content. I've been on the web enough to know never trust the web! People are awful and will destroy things! Instead, I crafted a narrative around hope and passing on my past work and failures as potential seeds for inspiration and chances to upcycle unfinished work.
Inspiration:
The main inspiration for my project actually came from something fellow IMA student Vince Piccone used to ask during our Friday classes in the summer. Vince would often the visiting speakers how they bounced back from failures or ideas that don't pan out. It really made me reflect on all the folders of half written abandoned code and ideas that I couldn't figure out at the time, lost interest in etc.
Process:
Excuse my language, this was an absolute shit show. 36/48 hrs spent coding without really any guarantee that any of this would work. I was neck deep in unknown territory for me and working against the clock. My first course of action was to create some clickable particles. I experimented with instanced buffer geometries and buffer geometries in general as I had seen examples in Three.js website of numerous hoverable/clickable elements. I wanted to use particles instead because...I'm a sucker for particles and I also wasn't familiar / interested in finding and implementing uniqueID for instance buffers. Originally I wanted the center of the space to be an explosion frozen in time and the clickable elements to be shards of glass/fragments of crystals etc but it turns out there aren't many good free frozen 3D models of explosions online, most of what's available are c4d renders and I'm just not familiar enough with the actual 3d software to use them. Instead, again thinking about the more 'hopeful' narrative I was driving now I decided on using a 3D model of a tree as the center piece and having the particles as a sort of metaphorical fruit or flora. After the base visuals were finished I realized that I hadn't actually touched the core functionality yet and scrambled to search for ways to store image files or zip files on nedb. I found that you can store images as 64bit data but really images aren't projects or code, I needed a way to share projects. I could link people to Github repos but Github doesn't work like youtube. Private repos are truly private and don't have shareable links unlike unlisted videos. I wasn't interested in filling my Github with a bunch of trash repos and it also felt a little anti-climatic? I realized I had no choice but to be bold, go find a datastorage! I wasted a bunch of time with firebase because I didn't understand what it was and what I was looking for! I panicked and looking into AWS s3 buckets! After some fireplace chats with developer friends I realized that I just needed a db to contain links to the storage spaces and items. Realizing that the greatest gift from NYU was a permanent email and unlimited student google drive I realized my cloud storage was under my nose the whole time. I spent the better part of the night trying to learn how to use the drive api and somehow managed to get it working and connected to my sketch. My web application would now check my designated google drive folder for a list of items, return those items view/download links and pass them onto my Three.js sketch and assign each link to a particle to be accessed when clicked. Intending to make things a bit more immersive on a whim I hired a voice actor on fivver to do a 30 second monologue of script I jotted down from the POV of an aging digital curator. An aging version of me getting ready to pass the torch. Add some css keyframe animations, background ambience music and whala I have a 'cinematic' intro to my space. I wanted to add more visuals to clutter the space and really sell the aesthetic of an aging old man with old work scattered everywhere but ran out of time as I spent the better part of a night trying to deploy and host my project on godaddy my shared web hosting eventually having to switch to my own vps server space. Deployment is hard. With that the first rough draft of my project was done! Of course between every single feature implementation I described were about a million bugs and problems and roadblocks and at this very moment I'm fearful that my app will break at any moment. :(
Problems:
OH BABY HERE WE GO!
- Clickable Particles:
On paper this shouldn't be that hard, create a raycaster and then shoot it from your mouse and camera every time someone clicks. See if that raycaster is intersecting with any of the objects and do something or don't do something based on that event. The problem with particles was that when pushing a float32bufferarray of random positions to populate my pointcloud for some reason, when the total range was less than 150 or so the bounding boxes were all messed up. IE, whenever I created a random set of vector3 to hold positions with a range of less than 150, no matter where I clicked my raycaster would somehow intersect even if I clicked in empty space. I still don't know why the phenomena occurred. I considered the possibility that things were hidden behind each other, placed too close or too far so that what I thought was empty space was just populated by a hidden particle. I disproved this theory however by dropping my point population to 3, even when I could visibly see all three of my points and the distance between somehow their bounding boxes would cover the entire space in between! I never figured out what was causing this issue but instead managed to sacrifice a bit of performance to bypass the issue by scaling everything up and increasing the range to 200. Scaling the 3D object is much more expensive to do in application but it is what it is for now.
- Databases:
Not considering the sidetracking into firebase as an actual problem actually figuring out the google drive api was quite a battle. Google just assumes you're familiar with api's and developing and really doesn't hold your hand. I like having my hand held! You may look at the drive api documentation and think it's easy to read but to someone like me, it was unfortunately not. It assumes you have a basic knowledge of querying and api authentication keys etc and I just simply don't. As with all big companies they update their api often and tutorials online were more often than not deprecated to an unusable state. I spent a lot of time trying to get the basics of the API to work really w/o a full understanding of refresh tokens vs auth tokens, how long I can use them for etc.
- Async/Await:
This is a continuation of my database woes as the the flow of information relied heavily on js promises, asynchronous functions etc. The only problem is that I'm not super familiar with promises and async coding, I ran into a huge number of timing errors simply because I lacked an understanding of when promises get fulfilled and what I can do with the data before and after. I didn't know if my empty array was pending, what that really meant etc, all I knew was that my data was not coming through when I was trying to draw everything.
- Deploying:
Truly the biggest nightmare that I didn't see coming at all, I intended to finish up the visuals, add some more textures and fragment esque geometries to my sketch etc after I deployed a version for safety. 5 hours later and 12 hrs before the presentation all I had were a million errors and no deployed sketch. I was using shared hosting via godaddy and information was scarce on how to run a node.js app on shared hosting. There are various 'supposed' solutions and wget grep curl commands that theoretically allow me to download node onto my shared hosting but none of them seemed to work for me. The biggest issue with shared hosting is the lack of root access and ability to add node.js to my server. Obviously without node.js installed I would have no way of getting my app working. After 5 hrs and no success I did some more digging and got a cheap vps server where I had full root access to. It was pretty barebones and didn't have any gui or control panel so I had to dig out my terminal and ssh notes and work everything from the command line. An interesting note is that I found out for whatever reason, some of my dependencies only work on node version 14.18.1, if you have the most up to date version of node you will run into errors!
Code Breakdown:








Future Iterations:
I fully intend to clean up the code in coming days when my brain comes back to normal and I pay off my sleep debt, add some more visuals and fix up the bottlenecks to make everything run a bit smoother.
Live Site / Github:
http://72.167.223.17:3001/
https://github.com/fakebrianho/avenueGlitch