# Grayhat Blog Tag: Development > Expanded public blog context for posts tagged Development. ## Page - [Development Tag](https://grayhat-company-blog.grayhatstudio.workers.dev/blog/tag/development) - [Development Tag LLM Context](https://grayhat-company-blog.grayhatstudio.workers.dev/blog/tag/development/llms.txt) - [Root LLM Context](https://grayhat-company-blog.grayhatstudio.workers.dev/blog/llms.txt) - [Root Full LLM Context](https://grayhat-company-blog.grayhatstudio.workers.dev/blog/llms-full.txt) - [Tag API](https://grayhat-company-blog.grayhatstudio.workers.dev/blog/api/public/v1/tags/development) ## Tag Details - Slug: `development` - Description: Coding, architectures, stacks and more. Build like a Grayhatter. - Post count in current snapshot: 7 ## Current Posts - [Full Stack Deployment: Setting Up CI/CD for Node.js Applications on AWS with Custom Domains](https://grayhat-company-blog.grayhatstudio.workers.dev/blog/full-stack-deployment-setting-up-ci-cd-for-node-js-applications-on-aws-with-custom-domains) - This comprehensive guide will walk you through establishing a professional CI/CD pipeline for Node.js applications on AWS EC2, complete with custom domain configuration. - [Creating an MVP for an unofficial v0.dev VS Code Extension clone](https://grayhat-company-blog.grayhatstudio.workers.dev/blog/creating-an-mvp-for-an-unofficial-v0-dev-vs-code-extension-clone) - The race to generate React UI code in VSCode ensues. - [Pixels to Players: How Good Game Designs are Executed](https://grayhat-company-blog.grayhatstudio.workers.dev/blog/pixels-to-players-how-good-game-designs-are-executed) - Taking a game from an idea to reality is hard. How do you navigate through a sea of endless ideas and technologies, to deliver something... fun? - [Building a Unity Plugin in JavaScript](https://grayhat-company-blog.grayhatstudio.workers.dev/blog/building-a-unity-plugin-in-javascript) - Make your JS Library compatible with Unity. - [Create Multiplayer Web Games, Faster](https://grayhat-company-blog.grayhatstudio.workers.dev/blog/create-multiplayer-web-games-faster) - We built a React/Vite-powered game engine, powered by Playroom. - [Sign in with Adobe in a Next.js App](https://grayhat-company-blog.grayhatstudio.workers.dev/blog/sign-in-with-adobe-in-a-next-js-app) - Use the power of Adobe to authenticate your Next app. - [Build games in Swift](https://grayhat-company-blog.grayhatstudio.workers.dev/blog/build-games-in-swift) - Going down the memory lane of child play, I think of the days when the world seemed so much bigger from a little boy’s eyes playing Temple Run on a borrowed iPhone - a work of enormous wonderment. Lost in the labyrinth of my favourite video game, I yearned to be part of its magical universe. A single thought endlessly echoed in my mind: "How is this game created? I want to make games like this!" As the years passed and I grew, it was no surprise that I found myself on the path of a developer. W ## Child Route Content ### [Full Stack Deployment: Setting Up CI/CD for Node.js Applications on AWS with Custom Domains](https://grayhat-company-blog.grayhatstudio.workers.dev/blog/full-stack-deployment-setting-up-ci-cd-for-node-js-applications-on-aws-with-custom-domains) - Slug: `full-stack-deployment-setting-up-ci-cd-for-node-js-applications-on-aws-with-custom-domains` - Published: 2025-05-13T15:00:41.000+05:00 - Updated: 2025-05-13T15:00:41.000+05:00 - Reading time: 9 min - Tags: DevOps, Cloud, Automation, Deployment, Development, Software Engineering, Amazon Web Services (AWS) - Authors: Syed Abdullah Nasir - Visibility: public 💡This is a repost from Abdullah's original blog on Medium. Check it out here: https://medium.com/@nasirabdullahsyed/full-stack-deployment-setting-up-ci-cd-for-node-js-applications-on-aws-with-custom-domains-8924217cb1a4In today’s competitive digital landscape, the ability to deploy applications quickly and reliably is essential for development teams. This comprehensive guide will walk you through establishing a professional CI/CD pipeline for Node.js applications on AWS EC2, complete with custom domain configuration. Whether you’re a solo developer or part of a larger team, these automation techniques will streamline your workflow and ensure consistent deployments. # Understanding CI/CD and Its Benefits Continuous Integration and Continuous Deployment (CI/CD) revolutionizes the software development lifecycle by automating testing and deployment processes. Instead of manually transferring files and restarting services, a well-configured CI/CD pipeline handles these tedious tasks automatically when you push code changes to your repository. The benefits include: - Reduced human error during deployments - Faster release cycles - Consistent testing before production deployment - Easier rollbacks when issues arise - Better collaboration within development teams # Prerequisites Before we dive into implementation, ensure you have: - An active AWS account with permissions to create and manage EC2 instances - A Node.js application ready for deployment (either existing or new) - A GitHub repository containing your application code - A domain name (if implementing the custom domain section) # Part 1: Setting Up Your AWS Infrastructure # Launching an EC2 Instance Let’s begin by creating the server that will host your application: - Log in to your AWS Console and navigate to the EC2 Dashboard *****AWS EC2 Dashboard****- Click the “Launch Instance” button - Select an appropriate Amazon Machine Image (AMI). For Node.js applications, Ubuntu or Amazon Linux 2 are excellent choices due to their stability and widespread support *****EC2 Launch Instance Section 2 — Application and OS Images (Amazon Machine Image)****- Choose an instance type. For smaller applications or testing environments, the free-tier eligible t3.micro is sufficient. Production applications may require more resources depending on traffic expectations *****EC2 Launch Instance Section 3 — Instance type****- Configure a key pair. This is critical for secure SSH access to your instance. Either create a new key pair or select an existing one, but ensure you download the private key file (.pem) if creating a new one *****EC2 Launch Instance Section 4 — Key pair (login)*********EC2 Launch Instance Section 4.1 — Key pair (login) — Create key pair Popup****- Configure security groups to allow the necessary network traffic: - SSH (port 22): Restrict to your IP address for security - HTTP (port 80): Allow from anywhere (0.0.0.0/0) - HTTPS (port 443): Allow from anywhere (0.0.0.0/0) *****EC2 Launch Instance Section 5 — Network settings****- Configure storage settings: - For most Node.js applications, the default storage allocation (8 GB) is sufficient - Use General Purpose SSD (gp2 or gp3) for balanced performance - Consider increasing storage if you anticipate **storing large media files**, **accumulating extensive logs**, **hosting databases locally (though a separate RDS instance is recommended for production) - **You can always increase storage later if needed *****EC2 Launch Instance Section 6 — Configure storage****- Launch the instance and note the Public IP address assigned to it *****EC2 Launch Instance Section 8 — Summary*********EC2 Instance Tab****# Setting Up the Server Environment After launching your EC2 instance, you’ll need to install the necessary software: - Connect to your instance via SSH: *****EC2 Instance — Connect Section — SSH Client Tab****ssh -i /path/to/your-key.pem ubuntu@your-ec2-public-ip - Update the package repositories: sudo apt update - Install Node.js and npm: sudo apt-get install -y nodejs - Install Nginx to act as a reverse proxy and check its status: sudo apt-get install nginx sudo systemctl start nginx sudo systemctl enable nginx sudo systemctl status nginx - Install PM2, a process manager that will keep your Node.js application running: sudo npm install -g pm2 At this point, navigating to your EC2 instance’s public IP address *http://your-ec2-public-ip/* in a browser should display the default Nginx welcome page, confirming that your web server is working correctly. # Part 2: Configuring GitHub Actions for CI/CD GitHub Actions provides an elegant way to implement CI/CD directly within your GitHub repository. We’ll set up a workflow that automatically deploys your application whenever changes are pushed to the main branch. # Setting Up a Self-Hosted GitHub Runner Unlike GitHub’s cloud-based runners, a self-hosted runner gives you direct access to your EC2 instance during deployment: - In your GitHub repository, navigate to Settings > Actions > Runners. *****GitHub Repository Settings — Actions Tab****- Click “New self-hosted runner” - Select “Linux” as the operating system. - Follow the provided instructions to download, configure, and run the GitHub Actions runner on your EC2 instance. *****GitHub Repository Settings — Actions Tab — New Runners Setup****Once installed, set up the runner as a system service to ensure it runs continuously: cd ~/actions-runner sudo ./svc.sh install sudo ./svc.sh start Verify that the service is running: sudo ./svc.sh status # Creating the GitHub Actions Workflow Now, create the workflow definition that will trigger your deployments: - Add your applications environment variables as a GitHub Secret *****GitHub Repository Settings — Secrets and Variables Tab*********GitHub Repository Settings — Secrets and Variables Tab — New Repository Secret Setup****- In your repository, create a directory structure .github/workflows/ - Add a file named deploy.yml with the following content: name: Node.js CI/CD # Trigger the workflow on pushes to the "main" branch on: push: branches: [ "main" ] jobs: build: # This job runs on your self-hosted runner runs-on: self-hosted steps: # Step 1: Checkout the latest code - uses: actions/checkout@v4 # Step 2: Setup Node.js environment - name: Use Node.js 20.x uses: actions/setup-node@v3 with: node-version: '20.x' cache: 'npm' # Step 3: Install dependencies - run: npm ci # Step 4: Set up environment variables # This step assumes you've stored your env variables as GitHub Secrets - run: | touch .env echo "${{ secrets.PROD_ENV }}" > .env # Step 5: Build the project if needed - run: npm run build --if-present # Step 6: Restart the application using PM2 - run: pm2 restart node-app || pm2 start server.js --name node-app This workflow performs several important functions: - Checks out your code on the EC2 instance - Sets up the appropriate Node.js version - Installs dependencies with npm ci (which is faster and more reliable than npm install) - Creates an environment file with your secrets - Builds your application if needed - Starts or restarts your application with PM2 # Configuring Nginx as a Reverse Proxy Now, set up Nginx to direct incoming web traffic to your Node.js application: sudo nano /etc/nginx/sites-available/default Replace the default configuration with: server { listen 80; server_name _; # For API endpoints location /api { rewrite ^\/api\/(.*)$ /api/$1 break; proxy_pass http://localhost:4000; # Adjust port to match your application proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } Test the configuration and restart Nginx: sudo nginx -t sudo systemctl restart nginx # Part 3: Adding a Custom Domain A professional application should have a proper domain name rather than an IP address. Let’s configure your application to use your custom domain. # Setting Up DNS Records - Log in to your domain registrar’s dashboard (e.g., Namecheap, GoDaddy, Route 53). - Navigate to the DNS management section for your domain. - Create A records pointing to your EC2 instance: - Type: A Record - Host: @ (for root domain) - Value: Your EC2 instance’s public IP address - TTL: 3600 (or recommended value) - For the www subdomain: - Type: A Record - Host: www - Value: Your EC2 instance’s public IP address - TTL: 3600 # Updating Nginx Configuration for Your Domain - Create a new Nginx configuration file for your domain: sudo nano /etc/nginx/sites-available/default - Add the following configuration: server { listen 80; server_name your-domain.com www.your-domain.com; # For API endpoints location /api { rewrite ^\/api\/(.*)$ /api/$1 break; proxy_pass http://localhost:4000; # Adjust if needed proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } # For serving static content or frontend location / { proxy_pass http://localhost:4000; # Adjust if needed proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } - Enable the new configuration: sudo ln -s /etc/nginx/sites-available/your-domain.conf /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl restart nginx # Securing Your Application with SSL/TLS Adding HTTPS encryption is crucial for modern web applications: - Install Certbot and the Nginx plugin: sudo apt update sudo apt install certbot python3-certbot-nginx - Obtain and install SSL certificates: sudo certbot --nginx -d your-domain.com -d www.your-domain.com - Follow the prompts to complete setup, choosing to redirect all HTTP traffic to HTTPS. - Certbot automatically configures renewal, but you can test it: sudo certbot renew --dry-run After SSL configuration, your Nginx setup will be updated to handle HTTPS connections securely. # Part 4: Verifying and Testing the Deployment After completing the setup, it’s time to verify that everything works as expected: - Push a change to your repository: git add . git commit -m "Test CI/CD deployment" git push origin main - Monitor the GitHub Actions workflow in your repository’s Actions tab. - Once the workflow completes, visit your domain or EC2 public IP address to verify that your application is running correctly. - Check the PM2 status on your EC2 instance: pm2 status # Advanced Optimizations To further enhance your deployment, consider these advanced optimizations: # Allocating an Elastic IP An Elastic IP ensures your application remains accessible even if your EC2 instance is restarted: - In the AWS Console, navigate to EC2 > Elastic IPs. - Allocate a new Elastic IP address. - Associate it with your EC2 instance. - Update your DNS A records to point to this new Elastic IP. # Implementing a CDN For applications serving users across different geographic regions, a CDN can significantly improve performance: - Set up AWS CloudFront or another CDN service. - Configure the CDN to use your domain as the origin. - Update your DNS records to point to the CDN distribution. # Setting Up Monitoring and Logging Implement monitoring to stay on top of your application’s health: - Install a monitoring agent like AWS CloudWatch or set up Prometheus. - Configure alerting for critical metrics like CPU usage, memory utilization, and disk space. - Set up centralized logging with tools like CloudWatch Logs, ELK Stack, or Graylog. # Common Troubleshooting Tips If you encounter issues during setup, check these common problem areas: - **DNS Resolution Issues**: Use nslookup your-domain.com to verify DNS propagation. - **Connection Refused Errors**: Check that your security groups allow traffic on the necessary ports. - **Application Not Running**: Check PM2 logs with pm2 logs node-app. - **Nginx Configuration Problems**: Review error logs with sudo tail -f /var/log/nginx/error.log. - **SSL Certificate Issues**: Ensure that Certbot completed successfully and check for certificate errors in browser developer tools. # Conclusion You’ve now set up a professional-grade CI/CD pipeline for your Node.js application on AWS EC2, complete with a custom domain and HTTPS encryption. This automation will save you countless hours of manual deployment work while ensuring consistent and reliable updates to your application. By leveraging GitHub Actions, you’ve created a streamlined workflow that automatically deploys your code whenever changes are pushed to your repository. This approach facilitates rapid iteration and helps maintain a consistent development experience across your team. The addition of a custom domain with SSL/TLS encryption provides a professional appearance and ensures secure communication between your users and your application. Remember to maintain your infrastructure by keeping your server updated and monitoring your application’s performance. For more advanced scenarios, consider exploring container-based deployments with Docker and Kubernetes, which can provide even greater flexibility and scalability for complex applications. Happy coding and deploying! ### [Creating an MVP for an unofficial v0.dev VS Code Extension clone](https://grayhat-company-blog.grayhatstudio.workers.dev/blog/creating-an-mvp-for-an-unofficial-v0-dev-vs-code-extension-clone) - Slug: `creating-an-mvp-for-an-unofficial-v0-dev-vs-code-extension-clone` - Published: 2024-08-19T15:30:04.000+05:00 - Updated: 2024-08-19T16:46:07.000+05:00 - Reading time: 5 min - Tags: Developer Tools, Artificial Intelligence, Development, Codegen, Copilot, GitOps, AI, Open Source - Authors: Asher Siddique, Muhammad Usama Rashid - Visibility: public **This extension is in no way affiliated with v0.dev or Vercel. It's just a dummy pet project we made to test out code generation in VSCode. We do aim on pursuing similar goals, but definitely with a different name 🥸Before we started working on this extension, another team with Grayhat was already working on an earlier version of the idea. The initial approach was to create a simple website embedded within VS Code using an iframe. **v0.dev** served as the core interface where users could input prompts and receive generated React component code. However, the iframe approach quickly ran into issues, as the website was eventually blocked by various security measures within VS Code. This made us rethink our strategy and led to the decision to build a native VS Code extension without relying on any website outside of VS Code. ## **Planning** To streamline things, we started with creating a detailed game plan that outlined the core functionalities we aimed to implement in the extension's proof of concept. These core features included: - An input field for user prompts - Image upload functionality - Handling API calls to the hosted LLM and processing responses - Displaying the generated React components as text in a UI element Alongside these features, we established a timeline with specific delivery dates to keep the project on track. Once the game plan was set, our next step was to familiarize ourselves with the documentation on how extensions work in VS Code. This research was crucial in helping us understand the necessary APIs and the architecture of a typical extension. With this knowledge in hand, we proceeded to set up a basic extension, similar to a "Hello World" page in web development. This initial setup served as the framework on which we built the entire extension. ## **Researching the docs** After briefly exploring the documentation, we began searching for and testing the appropriate API that would allow us to create a chat-like view in the primary sidebar of VS Code. To our misfortune, we could not find one that met our needs right away. So, for the first iteration, we settled on creating a chat-like view within the main editor. The goal was to build a basic skeleton in the main editor first, with the plan to eventually move the entire interface to the primary sidebar in the next iteration. In this initial setup, we aimed to create a WebView in the main editor that asks for the description of the component. ** ** ** 0:00 /0:27 * **1× ** ** * For the code generation part, we initially decided on using Claude 3.5 Sonnet or GPT-4o, but realized that spending extra resources on just a proof of concept was unnecessary. Therefore, we moved ahead with codegen-350M-mono from a pool of free/open source LLMs such as StarCoder, CodeGeeX, open-LLAMA, and code-LLAMA, primarily due to its popularity. ## **The Development Phase** Development was broken down into phases. The first phase produced the first version upon which the rest of the extension was built. All phases followed the game-plans that were created before starting them. What do the game-plans do? They are the official documents that list the features, delivery date, feature assignment, and other technical details for the phase. For the first iteration, we kept it simple and only focused on getting the input prompt, calling the LLM through HuggingFace’s Inference API, and displaying the output. This was relatively simple, just a bunch of HTML and CSS, and calling some VS Code Extension API’s endpoints. For the second iteration, we made some improvements as well as added new features. The improvements included moving the chat panel from the editor window to the primary sidebar window. The first version had an extra step to launch the chat window, which was also removed in the second version so that the process would be straightforward. The feature that was added was a copy button so that the end user can use the generated code in their project. The third and final iteration involved implementation of syntax highlighting using Shiki syntax highlighter, and using VS Code UI library instead of default CSS styles for a similar look and feel. ## **The team** We were a team of two and the development of the extension was a collaborative effort, where we divided the work based on our strengths. Aitsam, focused on the front-end development, handling the design and implementation of the user interface, ensuring that the overall extension seemed a part of VS Code in terms of interface. On the other hand, Asher took charge of the backend development. The responsibilities were managing the API integration, handling the logic for making API calls to the LLM, integrating it with the front-end, and processing the responses. Asher's work ensured that the extension could communicate with the AI model properly. ## **Navigating the Constraints** The previous team's biggest blocker eventually turned out to be v0.dev's own website. The website didn't allow iframing in the VSCode soon after the initial launch, and the team tried its best to uncover the underlying APIs, but it was a hassle trying to setup Vercel Auth to work alongside the original website. There also wasn't an official REST API. For our team, the biggest blocker we faced while developing an MVP was the **LLM model**. What we failed to realize was that codegen-350M-mono was a good autocomplete LLM. What we actually wanted was something that could turn prompts into code. The first version of the MVP was tested out using codegen and the possible improvements were noted down. The search for an LLM led us to Mistral-7B, specifically Instruct-v0.3. Mistral turned out to be quite a good model, as it was able to handle engineered prompts and the output was on point as well. From the improvements that we noted down, the second biggest blocker that we felt was moving the chat panel from the editor in VS Code to the primary sidebar. This required a whole refactor of the HTML, and not to mention there wasn’t much in the documentation about using WebViews in the primary sidebar. This took a good half a week but we were able to implement it and the extension received a very natural look and feel. *## **Possible Improvements** One place where the extension could improve massively was the output UI element. Instead of displaying the generated code, we could instead output the render of the code. This would help the end user in quickly determining whether the generated component is correct or does it need to be generated again, all without launching their project again. Our team lead gave us this idea but it never came to fruition due to time constraints. ### [Pixels to Players: How Good Game Designs are Executed](https://grayhat-company-blog.grayhatstudio.workers.dev/blog/pixels-to-players-how-good-game-designs-are-executed) - Slug: `pixels-to-players-how-good-game-designs-are-executed` - Published: 2024-08-14T23:04:07.000+05:00 - Updated: 2024-08-15T11:11:02.000+05:00 - Reading time: 6 min - Tags: Game Design, Product Design, System Design, Design, Gaming, Multiplayer Gaming, Playroom, PlayroomKit, Development, Software Engineering - Authors: Maaz Tariq - Visibility: public ** Great video games are like great books or movies; they resonate with us because they reflect our own experiences, dreams, and fears Like a composer crafting a symphony or a painter stroking onto their canvas, designing a game is a similar creative endeavour to any other art. There are no ways to design a game and a million ways to create one simultaneously. Making a good game is like making a good movie, it is supposed to be an experience one goes through that leaves an impact and gives a new perspective. Crafting together a piece of media that can deliver enough sentimental value to keep players coming back, that is what game design is all about. ## Making your Game Relatable One of the key aspects of making a moving art piece is adding elements in the piece that help the audience relate to it. When one sees another character going through situations they have gone through in real life, it develops a bond with the character. This pattern is commonly seen with anime protagonists having very relatable personality traits or situations in even a supernatural world. ** It should be the experience, that is touching. What I strive for is to make the person playing the game the director ***- Shigeru Miyamoto*** *****Papers, Please****Invoking that feeling of relatability is a key part of keeping the players coming back. A good example of executing this strategy is “Papers, Please”. To say very loosely, it's a game about checking and approving documents. A very simple premise, but it is a hit game because the way it sets the mood and develops the scene is very natural. It reminds you of a paperwork-heavy office, it makes you feel like an actual clerk with all the tediousness that comes with it. flipping through pages to check for rules, the applicant’s documents missing or fraudulent cards and ID cards and you have to manage all this junk under a time limit. The authenticity of the experience sells the game. *****Katana Zero****The experience we want to invoke is not limited to experiences our player has personally experienced but also seen others experience in their vicinity. The video game “Celeste” does an excellent job of explaining what depression feels like to people who haven’t experienced it, helping them understand people who suffer from depression. “Katana Zero” is a game with an excellent storyline. It explains the struggles of a soldier dealing PTSD in a very supernatural, ongoing conspiracy theory setting. After going back and forth with some product teams, I've learned that this goes hand-in-hand with KYC (Know Your Customer). Something which might help you to narrow down an idea is to first do some bare-bone **audience research. **Who is the target audience you have the most access to, whether in your friends circle, community, or in your company's easiest access? What is daily life for them, what is entertainment, what makes their heads turn? Just some raw data from here, organized and transformed into a "player persona", can act as a prompt for you to brainstorm some better ideas - Then you can easily validate or verify your ideas by just bouncing them off of that persona. (you can even reach out to an audience member and present ideas to them) ## Using the Right Tools Invoking experience is one of, if not the greatest, priorities for a game designer. The designer must have tools capable enough to pull off the ideas they draft. A designer’s canvas is the engine they use. The way you cannot achieve on a smaller canvas what you can on a larger one. You cannot do things on an engine that is incapable of following through with the mechanics of your design. More often than not, the development-end of game-building is almost as artistic as the design side. It makes sense, given that you need to create a world which truly captures the emotion conveyed in the game, or at least having enough helpful snippets which can keep the code clean while building out the game. This usually drives companies to build custom game engines, or at least base them off of existing ones. Many times, technological advances are the reason for designing new experiences to human entertainment. Grayhat's npm package "create-multiplayer-game" is built to speed up the development process and simplify implementing game designs. We use it thoroughly when building out game prototypes - However, by the time the game reaches production, the engine does take a beating. But we use the new findings to improve the engine once more. The package aims to streamline the creation of React-based (more coming in the future!) multiplayer games, making it easier for developers to focus on the creative aspects of game design rather than being limited by technical challenges. *create-multiplayer-game (CMG) does lots of heavy lifting for you. It provides you with prebuilt modules so you don’t have to reinvent the wheel every time. CMG provides a silent router, letting you change game phases without any changes in the URL bar. This makes the game-flow entirely in control of the game itself and handles the possibility of cheating by messing with the URL to switch phases. It also has its own loading module which can show what file is being loaded in real time. All in all it has the essential parts of a video game for any kind of game prebuilt, so you can focus on the design instead of the execution. ## Learning from Retrospective “Meme, Chat, Robots” has a user interface and design similar to Meta apps. When talking about the game with Saad Bazaz, I learned Meme, Chat, Robots’ UI was designed by a talent at Meta. Using Radix, helps us make reusable components that can be used throughout the project, giving it a coherent look and feel. Addition of a silent react-router, one that can route to different pages without showing changes in the URL. While seemingly a small change, it makes a substantial difference for video games. A video game has to follow a game flow, unlike apps where users can go to whatever page they like. moving from stage 1 to stage 2, or from a cut-scene to gameplay requires a game flow that cannot be tampered with from the URL. ## Get Your Hands Dirty As a game designer, your tools are the technologies and languages you build games with and your canvas is the game engine you use. To translate your designs into the game, you will have to know how the game works. How it's built and why it does what it does. You can’t get away with skipping learning a phase of development, learning development helps the design be grounded and realistic. *## Recycle your Trash There’s no such thing as bad ideas. I have used parts of stories and themes I wrote in my high school essays in complete products! Stories and ideas that don’t seem like a good fit are just in the wrong place. Always save your drafts and keep them close whenever you want to brainstorm a new theme or look for your game. Have different folders for all kinds of media you draw inspiration from, then try to fit them to any future projects. Make different folders for music and art and keep adding any ideas in those folders. ** The first mark on an empty canvas is the most difficult to make Having a stash of resources like these help you form your first stroke on a blank canvas. ## Verdict As daunting as designing a video game may seem, following only a couple of principle can guarantee an interesting result. Trial and error is part of the game, like any design process. Pair it with some direction and you’re good to go! Here’s a small recap: - Design the experience, not the app - Bind real-life experiences with the video game’s experience - Use a capable game engine, that fits your game aesthetic and can pull off your design - Learn and apply from previous projects, embrace failure - Learn and experience every part of the dev process firsthand Now building the latest video game, I have learnt a few more lessons to help me contribute to CMG. Stay tuned for more in-depth articles discussing game design and CMG! ### [Building a Unity Plugin in JavaScript](https://grayhat-company-blog.grayhatstudio.workers.dev/blog/building-a-unity-plugin-in-javascript) - Slug: `building-a-unity-plugin-in-javascript` - Published: 2024-05-04T14:21:06.000+05:00 - Updated: 2024-08-31T13:07:31.000+05:00 - Reading time: 6 min - Tags: Development, Gaming, Multiplayer Gaming, Software Engineering - Authors: Talha Momin - Visibility: members **Playroom for Unity is open-source. Check it out here: https://github.com/asadm/playroom-unity**Interested in trying out Playroom for Unity? Check the docs! Join the Discord channel too in case you need help, you'll find me lurking there sometimes. 😁Creating a game is no easy task, and crafting a multiplayer experience adds an even greater level of difficulty. But thanks to industry experienced developers who've created numerous tools which make the process of creating multiplayer games easier and more productive, developers can now focus on creating fun and immersive experiences for their users, and not worry about the networking side. One growing platform for this purpose is PlayroomKit by Playroom, which mainly focuses on multiplayer web-based party games. I'm a Unity Developer, so I've had my eyes on similar multiplayer plugins for quite a while. Some of them are: - **Normcore:** https://normcore.io/ - **Photon:** https://assetstore.unity.com/packages/tools/network/photon-unity-networking-classic-free-1786 - **PlayFab:** https://learn.microsoft.com/en-us/gaming/playfab/features/multiplayer/lobby/lobby-matchmaking-sdks/multiplayer-unity-plugin-quickstart - **Hathora:** https://hathora.dev/ One of my biggest complaints (and the community's) is how hard it is to get things up and running with these libraries. All that previous knowledge helped me, when I had to implement a plan to create PlayroomKit for Unity, keeping the objective in mind, making sure I didn’t hurt Developer Experience, and using my knowledge in Unity and hacking around in C# and JS. ### The Goal **Combine the ease of PlayroomKit with power of the Unity engine.The PlayroomKit package is super simple to get started with… in JS, at least. That’s a developer experience we needed to port to Unity. At the same time, we had to make the Unity library at feature parity with the JS library, following the exact same API. (That makes it easier to write docs, at least 😃) Here our first **problem** arises which is quite easy to pinpoint: Unity uses C# and PlayroomKit is a JavaScript package. So some interoperability had to occur. To achieve this, we had the following approaches: - Convert the JS library to C#, or, - Use a JavaScript Interpreter for .NET (JINT), or, - Use the Interaction with browser scripting provided by Unity itself. **If you want to go deeper into the thought process of “why” we went with our final approach, I highly recommend reading Playroom’s official blog on this very topic.### The Approach We went with the **third approach**, referring the Unity docs. In short, the workflow is like this: - We work with 2 files: a JSLIB (JavaScript Library) and C# class. - The JSLIB file acts as a bridge between PlayroomKit (or any other JS library) and C# (Unity) *What I call "The Bridge".The figure above shows basic working of the system. ### Problem 1: Passing Data The Unity documentation shows an example where the primitive datatypes are being used to pass data between C# and JS. This process of converting is known as: ***Marshalling.** This process involves converting an object's memory representation into a format suitable for storage or transmission, especially across different runtimes.*The documentation gives us a good starting point with examples for the basic datatypes: Hello: function () { window.alert("Hello, world!"); }, HelloString: function (str) { window.alert(UTF8ToString(str)); }, PrintFloatArray: function (array, size) { for(var i = 0; i > 2) + i]); }, AddNumbers: function (x, y) { return x + y; }, StringReturnValueFunction: function () { var returnStr = "bla"; var bufferSize = lengthBytesUTF8(returnStr) + 1; var buffer = _malloc(bufferSize); stringToUTF8(returnStr, buffer, bufferSize); return buffer; }, And in C# we will define the functions like this: [DllImport("__Internal")] private static extern void Hello(); [DllImport("__Internal")] private static extern void HelloString(string str); [DllImport("__Internal")] private static extern void PrintFloatArray(float[] array, int size); [DllImport("__Internal")] private static extern int AddNumbers(int x, int y); [DllImport("__Internal")] private static extern string StringReturnValueFunction(); To use these functions, we can call them like so: void Start() { Hello(); HelloString("This is a string."); // sending a string to JS float[] myArray = new float[10]; PrintFloatArray(myArray, myArray.Length); int result = AddNumbers(5, 7); Debug.Log(result); Debug.Log(StringReturnValueFunction()); }Now this is all great, but the issue arises when we have to deal with async code or functions with callbacks. ### Problem 2: Async Code or Callbacks?! There are great discussions on the Unity Forums regarding using async functions and for passing callbacks as well. In the case for PlayroomKit, instead of using async / await, we went with providing callbacks, (PlayroomKit already provides callback parameters wherever required). The pattern here is something like so: ### [Create Multiplayer Web Games, Faster](https://grayhat-company-blog.grayhatstudio.workers.dev/blog/create-multiplayer-web-games-faster) - Slug: `create-multiplayer-web-games-faster` - Published: 2024-05-04T10:31:32.000+05:00 - Updated: 2024-08-31T13:41:49.000+05:00 - Reading time: 2 min - Tags: Development, Multiplayer Gaming, Gaming, JavaScript, Developer Tools - Authors: Syed Abdullah Nasir - Visibility: public **Open-source Product Announcement! Check out create-multiplayer-game on NPM and GitHub. Currently in alpha.***Imagine this**...* You have a great idea for your next indie game, and since the world is online-first, you dive into the world of multiplayer game development, but you want to skip the tedious setup process. Sockets? Firebase Realtime DB? Eventually, you give up on multiplayer, and focus on building a great single-player experience first. When you do, and you put off multiplayer to the end, you end up having to refactor a lot of code to make it "multiplayer-ready". What if games were built **multiplayer-first**? That's why we built a React/Vite powered game template, powered by Playroom. It swiftly conjures up a multiplayer game template in React, so you can focus on bringing your gaming vision to life. npx create-multiplayer-game@latestIt will ask you a few small questions to personalize your game. Have a look. *Works great with macOS and Linux.**Name Your Game: **First off, we need a name for your masterpiece. What will you call it? **Project Name: **Need a project name, or are you happy with the default generated one? Feel free to customize it as you like! **Choose Your Template: **Now, which template suits your fancy? Use your arrow keys to browse the options: *Option A:* "vite-react-ts": A ReactJS project with Vite, crafted in TypeScript. It's equipped with PlayroomKit for multiplayer magic, along with an array of game components, sounds, and interactions. Usually the top choice. *Option B:* "next-ts'': A NextJS project in TypeScript, powered by PlayroomKit for multiplayer functionality. Once you've made your choice, sit back as we download your selected template. Then, you'll be greeted with a message: "Project initialized at . Happy Coding!" ### What's next? - We're building a mechanism for you to keep updating your game, as we improve our templates. - We're building a useful Chrome DevTool for debugging game states (no more hardcoding or adding "cheats" to go forward in a game). - Some premium templates with some extra goodies. Read more here: https://grayhat.studio/games/pricing *We love open source, bringing useful tech to builders, and contributing to the overall knowledge stream. A lot of our work is R&D-based and on experimental tech. If you're interested in working with or for *Grayhat*, DM or comment!* **This article was authored by** Syed Abdullah Nasir, **Software Engineer at Grayhat.** ### [Sign in with Adobe in a Next.js App](https://grayhat-company-blog.grayhatstudio.workers.dev/blog/sign-in-with-adobe-in-a-next-js-app) - Slug: `sign-in-with-adobe-in-a-next-js-app` - Published: 2023-10-20T13:07:00.000+05:00 - Updated: 2024-08-31T13:42:30.000+05:00 - Reading time: 3 min - Tags: JavaScript, Development, Next.js, NextAuth - Authors: Saad Bazaz - Visibility: members **You can see the relevant Pull Request, and all the provider's code mentioned in this article, on GitHub: https://github.com/nextauthjs/next-auth/pull/8890Whether you're a seasoned Auth geek, or a newbie, NextAuth (soon, Authjs.dev) is the auth lib to use. That's why we chose it for Omni, since we needed a stable Auth solution so we could focus on experience. Adobe is a popular platform for creatives, and is widely used (obviously) internally at Adobe. From Behance, to Creative Cloud, and to Adobe Stock and many more, it's sort of the defacto for professional creatives. I believe it's a staple for products building in the art, media and design space, and sits right next to Google and ArtStation, and that made it a low-hanging fruit as an authentication feature for Omni's tools. This article has been made after painful hours understanding Adobe's OAuth 2.0 documentation. But there's one thing I'm grateful for; **standards** in the boring stuff. OAuth 2.0 has really made life much easier than before. The wild days of crappy Auth setups are long gone, and almost all major providers follow the standard to quite an extent, making integrations a breeze. At least for the libraries and builders who understand the standard. ## How to implement Adobe OAuth 2.0 Authentication ### 1. Create an account on Adobe's Developer Console Pretty straightforward. Use your team's account to create a Developer account on Adobe. You should be able to see a console here: https://developer.adobe.com/console/home *An important question: *What information do you want from Adobe? This is something that differs for each app. In our case, we just needed the bare minimum, so we went with Adobe Stock. You can see all the available scopes in OAuth 2.0 here. ### 2. Create a project On the Adobe Developer Console, create a new project for the app you're working on. ### 3. Add an API In the project you just created, you need to add an API. We chose Adobe Stock here, as mentioned earlier, because it gave us what we needed at the bare minimum. Make sure to choose an API with the **OAuth Web App **option. That's the one which'll work with Next.js. Read more on all the types here. ### 4. Configure the Credential **Default redirect URI: **This is the domain where you're hosting your app. Use https. **Redirect URI pattern: **This is a regex. This is the one I use: https://({{YOUR-PROJECT-NAME-ON-VERCEL}}-.*-{{YOUR-TEAM-NAME-ON-VERCEL}}\.vercel\.app|localhost)(.*)/api/auth/callback/adobe### 5. Install NextAuth Read more on that here. Set it up as per your requirements. ### 6. Add the Adobe Provider If, by the time you're reading this article, our PR is not part of the main source code, you'll have to add a custom OAuth Provider. No worries, here's the code for that: ### [Build games in Swift](https://grayhat-company-blog.grayhatstudio.workers.dev/blog/build-games-in-swift) - Slug: `build-games-in-swift` - Published: 2023-09-27T16:07:00.000+05:00 - Updated: 2024-05-14T13:13:06.000+05:00 - Reading time: 4 min - Tags: Development, Gaming, Swift, Apple, Apple Developer, Multiplayer Gaming, iOS, Playroom, PlayroomKit - Authors: Anonymous - Visibility: public *Apple is making moves into the gaming world. You might want to prepare yourself for it.Going down the memory lane of child play, I think of the days when the world seemed so much bigger from a little boy’s eyes playing *Temple Run* on a borrowed iPhone - a work of enormous wonderment. Lost in the labyrinth of my favourite video game, I yearned to be part of its magical universe. A single thought endlessly echoed in my mind: "How is this game created? I want to make games like this!" As the years passed and I grew, it was no surprise that I found myself on the path of a developer. With each step, I honed my skills and explored various avenues. But destiny had a plan of its own, and it led me to the realm of Swift. *Perhaps the little boy within me had awakened to redirect me to a path I was destined to tread.* And there, I discovered Swift, Apple's remarkably user-friendly programming language, waiting to breathe life into those long-cherished dreams. As Apple dives further into entertainment and gaming with hardware like the VisionPro, and with its own custom M1 chips, we may see a surge of Apple-native gaming engines, a more refined Unity and Unreal, machine learning frameworks, and perhaps, a new era of desktop and mobile gaming with Apple. Let’s step into the world of gaming in Swift, uncovering the tools, frameworks, and tips that make it an exciting journey for budding game developers. ### Starting off with a simple, thought provoking question - why Swift? **Blazing fast performance. **Like a high-performance sports car in the programming world, it is built for speed and efficiency. When it comes to gaming, performance is key, and Swift ensures your games run seamlessly and without a hitch. Swift is optimized for Apple, and ships natively for all OSes - iOS, iPadOS, macOS, watchOS, to name a few. **Go beyond Apple devices. **Originally designed for Apple gadgets, Swift has spread its wings. You can use it to create games not only for iOS and macOS but also for other platforms, reaching a broader audience. Making a greater impact. **Seamless integration. **It plays harmoniously with Apple's tech toolbox, including SpriteKit, SceneKit, and ARKit. This synergy simplifies game development, letting you harness cutting-edge features with ease. ### How does an app dev do game dev? Game development is pretty similar to app development - it just involves more creative processes, however these can be easily mapped to one's app development pipeline: - **Idea Generation: **Start with a spark of inspiration. Think about what kind of game you want to create. Is it a mind-bending puzzle, an adrenaline-pumping action-adventure, or perhaps a captivating simulation? - **Designing Gameplay: **Outline the rules, objectives, and gameplay mechanics. Consider how players will interact with your game world. - **Coding with Swift: **Dive into Swift to bring your ideas to life. Write the code that powers your game mechanics and characters. - **Testing and Tweaking: **Games evolve through testing. Playtest your game, gather feedback, and make improvements. - **Polishing Graphics and Sound: **Create captivating visuals and immersive audio to make your game come alive. - **Launching Your Creation: **When your game is ready, launch it and share it with the gaming community. Embrace player feedback to enhance your creation. While Swift is a great choice for game development, like anything in life, it certainly its has its cons, I have enlisted some below: - Platform Limitations: While Swift has expanded its horizons, it's still primarily associated with Apple platforms. - Types of Games: Swift seems better for* point-and-click *games, *puzzle *games, and games with native UI. Swift may not be a good choice for complex games involving interactions and physics-based game mechanics. While there are open-source game engines in Swift like GateEngine available, their support is limited and it's just good for pet projects. - Learning Curve: Learning Swift and game development can be a bit challenging, especially for beginners. - Resource Availability: The Swift game development community is smaller compared to other game development languages like Unity or Unreal Engine. On the flipside, opting for a native programming language like Swift over web technologies offers several advantages: - Performance: Native languages are finely tuned for specific platforms, delivering superior performance compared to web-based technologies that run in a web browser. - Access to Hardware: Native languages have direct access to hardware resources, enabling more efficient utilization of device capabilities such as graphics and sensors. - Offline Play: Native games can be enjoyed offline, ensuring a seamless gaming experience without needing an internet connection. - Platform Integration: Native languages offer deeper integration with platform-specific features and libraries, resulting in a more polished and immersive gaming experience. Taking Swift game development a step further, my team built PlayroomKit's SDK for Swift, enabling easy multiplayer between platforms. This groundbreaking advancement involves wrapping a JavaScript SDK in Swift, providing you with the ability to seamlessly incorporate web technologies into your Swift-based games. This, in turn, opens up opportunities for cross-platform gameplay, expanding your game's reach to even greater heights. To showcase the power of PlayroomKit, we integrated it into a TicTacToe game. Simple, yet engaging. The result? A fun and interactive gaming experience that seamlessly combines the best of both worlds: Swift and web technologies. Swift - a secret doorway to your (*I mean* *our)* game development dreams. Whether you're painting 2D wonders with SpriteKit, exploring 3D universes with SceneKit, or unleashing your creativity with Metal, Swift equips you with the tools to make your gaming visions come alive. With passion, creativity, and a bit of Swift know-how, you're set for an incredible journey into the world of game development. Get ready to craft experiences that captivate players, bring joy, and make your mark in the gaming universe. It's time to let your gaming adventures begin! **Author:** Engr Sajid Khalil **Editor:** Fatima Majid