# Grayhat Blog Author: Anonymous > Expanded public blog context for posts by Anonymous. ## Page - [Anonymous Author](https://grayhat-company-blog.grayhatstudio.workers.dev/blog/author/anonymous) - [Anonymous Author LLM Context](https://grayhat-company-blog.grayhatstudio.workers.dev/blog/author/anonymous/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) - [Author API](https://grayhat-company-blog.grayhatstudio.workers.dev/blog/api/public/v1/authors/anonymous) ## Author Details - Name: Anonymous - Location: Not provided - Website: Not provided - Post count in current snapshot: 6 - Bio: Not provided ## Current Posts - [Python vs Mojo: Are we there yet?](https://grayhat-company-blog.grayhatstudio.workers.dev/blog/python-vs-mojo-are-we-there-yet) - Hey there! I am new to both Python and Mojo languages. In this repository, I went on a mission to explore and compare these two languages from scratch, knowing only the basics of programming (I started off knowing only the basics of C++). As I continue learning both languages, I'll be tracking my progress and updating the benchmarks in the following repository. Do give it a star ⭐️: https://github.com/grayhatdevelopers/mojo-vs-python-benchmarks/ Why did I do it? I've always wanted to explore - [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 - [I feel blue - Unveiling Culture Fit; An Immortal Myth of Recruitment](https://grayhat-company-blog.grayhatstudio.workers.dev/blog/i-feel-blue-unveiling-culture-fit-an-immortal-myth-of-recruitment) - We often find ourselves widening the gyre of recruitment practices in pursuit of filling teams with the right fit – hitting all the right notes of skill set, personality, and value. The quest to find the right fit to help us grow might as well get us on the path to make-believe land. Apologies for stumping on your bubble there, but as you run towards your familiar rock, you inadvertently overlook the diamond hidden in your path. Culturally-fit hiring strategies have set their roots deep in IT - [We built a multiplayer, web-based Mario-like game with PlayroomKit... in 7 days!](https://grayhat-company-blog.grayhatstudio.workers.dev/blog/we-built-a-multiplayer-web-based-mario-like-game-with-playroomkit-in-7-days) - How we transformed an open-source single-player game to multiplayer. - [Medusa.js for Entrepreneurs, Part 2: Features](https://grayhat-company-blog.grayhatstudio.workers.dev/blog/medusa-js-for-entrepreneurs-part-2-features) - Cloning the frontend, backend, and admin panel repositories results in a readily available template e-commerce application with all the basic user flows, from adding a product to a basket to placing and tracking orders. Furthermore, the administration panel has every capability imaginable for a template application. Below is a brief description of all the major features ready to use in the Medusa template app: User Side (Frontend) Below are some of the prominent features readily available fo - [Medusa.js for entrepreneurs, Part 1: Intro](https://grayhat-company-blog.grayhatstudio.workers.dev/blog/medusa-js-for-entrepreneurs-part-1-intro) - The world of e-commerce is experiencing unprecedented growth, with more businesses moving online each day to meet the demands of digital consumers. As the industry continues to evolve, the need for efficient, user-friendly, and powerful tools for creating e-commerce web applications has become more critical than ever. Enter MedusaJS: a powerful, open-source e-commerce platform that simplifies the process of building and managing an online store. In this blog, we'll explore the power of MedusaJS ## Child Route Content ### [Python vs Mojo: Are we there yet?](https://grayhat-company-blog.grayhatstudio.workers.dev/blog/python-vs-mojo-are-we-there-yet) - Slug: `python-vs-mojo-are-we-there-yet` - Published: 2024-05-05T23:21:29.000+05:00 - Updated: 2024-05-14T14:37:15.000+05:00 - Reading time: 11 min - Tags: None - Authors: Anonymous - Visibility: public Hey there! I am new to both Python and Mojo languages. In this repository, I went on a mission to explore and compare these two languages from scratch, knowing only the basics of programming (I started off knowing only the basics of C++). **As I continue learning both languages, I'll be tracking my progress and updating the benchmarks in the following repository. Do give it a star ⭐️: https://github.com/grayhatdevelopers/mojo-vs-python-benchmarks/## Why did I do it? I've always wanted to explore Python (because of how better it was than C++ according to many friends at university). During my internship at Grayhat, I was advised to learn Python **alongside** Mojo, given that they had a similar syntax. I took the time to read through Mojo's documentation. It seemed promising and interesting. The team at Modular has designed Mojo to be a superset of Python, and it's **specifically** built for complex mathematical coding, something that would be required in **Artificial Intelligence** (What I'm currently studying in University, and the current market boom 🤯). Since it's a newer language, I can also expect it to offer new features and improvements, aligned with modern-day requirements. This made me wonder: **Can Mojo be my daily driver? Can I use it to **learn **programming?It gives the community a good chance to see how well Mojo can really replace Python, especially for its **adoption by newcomers**. It's often said that: **“**If you can't explain it to a six-year-old, you don't understand it yourself.”**Let's see how well Mojo and Python can explain themselves to, well, me! ## Metrics for judging both the languages I set out with the following metrics to judge between the two: - (Which one of them was) **User-friendly** - (Which one of them was) **Easier to use** - (Which one of them is better in) **Performance and stability** The environment which I tested all this in: - OS: Ubuntu WSL on Windows 11 - Editor: VS Code - Version of Python: Python 3.10.12 - Version of Mojo: Mojo 0.7.0 (af002202) - My laptop specifications (Dell XPS 13): - Core i7 1165G7 @2.8GHz - 8GB DDR4 RAM - Integrated Graphics Now that we've gotten that out of the way... Let's get technical with some experiments! ## Experiments **Check the results below if you prefer not to go into the experiment details.### Results For all the codes, Python ran significantly faster than Mojo and beat Mojo, in speed, by a huge margin (at least in my case). ### Comparing the advantages of both 1: Python installation was much simpler compared to Mojo. Installing Mojo was not user-friendly; it would have been better if there was a one-click installation option for Mojo on Windows, similar to Python. 2: The syntax of Mojo and Python was quite similar, with the main difference being that in Mojo, you need to use Python functions by importing them. For example, to take user input, you have to import the "input" function from Python. This made Python easier to learn. For example to use the input function, I first need to import it from Python and then use it in Mojo: from python import Python py = Python.import_module("builtins") py.input("Enter your name")3: Mojo provided helpful explanations with each error, making it easier for me to understand and identify my mistakes. Python, on the other hand, lacked this feature, which is an advantage of Mojo. 4: The code itself requires a main() function to be called in Mojo for it to run while Python runs as is. i.e: *While Python can run without adding this main() function. Interesting design choice! 5: The Discord community of Mojo is very active and helpful. Their Discord has a chatbot which guides through every inconvenience with ease and is up to date with all the errors that I encountered while coding in Mojo For example: *This bot is equipped with the latest info regarding Mojo, so was a very helpful feature 6: Python proved to be more user-friendly for me, mainly due to its proper documentation (because of it being older than Mojo). Moreover, the commands in Python were straightforward and simple to use, unlike Mojo, where there were some instances like for example me clearly stating the variable type (requiring explicit variable declarations), a step which I didnt have to do in Python ### Programs - **Length of last word**: returning the length of the last word in the string. - **Student attendance record**: Whether or not the student is eligible for an attendance award - **Remove repeating letters**: Removing the adjacent letters (one being capital) in a string. - **Detect Capital letter usage** : Returning true if the usage of capitals in it is right. - **Find the difference**: Returning the extra letter among 2 strings ### Benchmarking and Testing The performance of both languages was benchmarked using **Hyperfine**. Programs were tested and outputs were compared to see which one of them was faster (ran an additional code for testing the Memory) ## Question 1 **Given a string s consisting of words and spaces, return *the length of the **last** word in the string. *A **word** is a maximal substring consisting of non-space characters only.**Python Code:** class Solution(object): def lengthOfLastWord(self, s): """ :type s: str :rtype: int """ enterword=s count=0 for i in range(len(enterword)-1,-1,-1): if enterword[i] != " ": count+=1 elif count>0: break return count **Mojo code:** from python import Python def lengthOfLastWord(enterword: String): py = Python.import_module("builtins") count = 0 for i in range(len(enterword)-1, -1, -1): if enterword[i] != " ": count += 1 elif count > 0: break print("Length of the last word:") print(count) def main(): input_string = "Hello World" lengthOfLastWord(input_string) Link: https://leetcode.com/problems/length-of-last-word/description/ ### Benchmarks **Benchmark 1 (Python):** python3 problem-1.py Time (mean ± σ): 11.1 ms ± 1.6 ms [User: 9.4 ms, System: 1.8 ms] Range (min … max): 8.8 ms … 22.1 ms 212 runs Avg memory: 8412k **Benchmark 2 (Mojo):** mojo problem-1.mojo Time (mean ± σ): 222.3 ms ± 9.7 ms [User: 238.4 ms, System: 28.6 ms] Range (min … max): 205.5 ms … 238.0 ms 14 runs Avg memory: 38548k ### Which performed better? The Python code ran 19.95 ± 3.02 times faster than Mojo code ## Question 2 **Given an integer x return true if x *is a palindrome and false otherwise***Python Code:** def checkRecord(attendance_record): attendance_record_str = str(attendance_record) absent_count = 0 late_count = 0 for i in range(len(attendance_record_str)): if attendance_record_str[i] == 'A': absent_count += 1 late_count = 0 elif attendance_record_str[i] == 'L': late_count += 1 else: late_count = 0 if late_count >= 3 or absent_count >= 2: print("The attendance record is not acceptable.") return False print("The attendance record is acceptable.") return True # def main(): checkRecord("PAALP") main() **Mojo Code:** from python import Python def checkRecord(attendance_record: String): py = Python.import_module("builtins") attendance_record_str = attendance_record absent_count = 0 late_count = 0 for i in range(len(attendance_record_str)): if attendance_record_str[i] == 'A': absent_count += 1 late_count = 0 elif attendance_record_str[i] == 'L': late_count += 1 else: late_count = 0 if late_count >= 3 or absent_count >= 2: print("The attendance record is not acceptable.") return False print("The attendance record is acceptable.") return True def main(): checkRecord("PAALP") Link: https://leetcode.com/problems/student-attendance-record-i/description/ ### Benchmarks **Benchmark 1 (Python):** python3 problem-2.py Time (mean ± σ): 11.9 ms ± 2.2 ms [User: 9.8 ms, System: 2.2 ms] Range (min … max): 8.8 ms … 23.0 ms 316 runs Avg memory: 8392k **Benchmark 2 (Mojo)**: mojo problem-2.mojo Time (mean ± σ): 236.4 ms ± 5.3 ms [User: 259.6 ms, System: 21.9 ms] Range (min … max): 228.0 ms … 243.9 ms 12 runs Avg memory: 39080k ### Which performed better? The Python code ran 19.78 ± 3.59 times faster than the Mojo code ## Question 3 **Given a string s of lower and upper case English letters. A good string is a string which doesn't have **two adjacent characters** s[i] and s[i + 1] where:- 0 **Python Code:** def makeGood(s): result = "" i = 0 while i **Mojo Code:** from python import Python def makeGood(s: String): py = Python.import_module("builtins") result = str("") i = 0 while i Link: https://leetcode.com/problems/make-the-string-great/ ## Benchmarks Time (mean ± σ) Range (min … max) Avg.Memory Runs Python 10.0 ms ± 2.4 ms 7.2 ms … 26.2 ms 8240k 111 runs Mojo 176.9 ms ± 17.0 ms 161.6 ms … 216.5 ms 39000k 13 runs ## Which performed better? The Python code ran 17.67 ± 4.61 times faster than the Mojo code. ## Question 4 **You are given a string s representing an attendance record for a student where each character signifies whether the student was absent, late, or present on that day. The record only contains the following three characters:- 'A': Absent. - 'L': Late. - 'P': Present. **The student is eligible for an attendance award if they meet **both** of the following criteria:- The student was absent ('A') for **strictly** fewer than 2 days **total**. - The student was **never** late ('L') for 3 or more **consecutive** days. **Return true *if the student is eligible for an attendance award, or* false *otherwise*.**Python Code:** def detectCapitalUse(word): uinput = str(word) number_of_capital_letters = 0 for i in range(len(uinput)): letter = uinput[i] if ord(letter) **Mojo Code:** from python import Python def detectCapitalUse(word: String): py = Python.import_module("builtins") uinput = word number_of_capital_letters = 0 for i in range(len(uinput)): letter = uinput[i] if ord(letter) Link: https://leetcode.com/problems/detect-capital/description/ ### Benchmarks **Benchmark 1 (Python):** python3 problem-4.py Time (mean ± σ): 11.1 ms ± 1.3 ms [User: 9.6 ms, System: 1.7 ms] Range (min … max): 9.8 ms … 17.4 ms 260 runs Avg memory: 8420k **Benchmark 2 (Mojo):** mojo problem-4.mojo Time (mean ± σ): 230.1 ms ± 10.1 ms [User: 249.7 ms, System: 26.7 ms] Range (min … max): 215.3 ms … 252.0 ms 13 runs Avg memory: 38820k ### Which performed better? The Python code ran 20.64 ± 2.52 times faster than the Mojo code ## Question 5 **You are given two strings s and t. String t is generated by random shuffling string s and then add one more letter at a random position. Return the letter that was added to t.**Python Code:** def findTheDifference(s, t): for i in range(len(t)): if s[i] != t[i]: result = t[i] break print("The difference is:", result) def main(): findTheDifference("abcd", "abced") main() **Mojo Code:** from python import Python def findTheDifference(s:String, t:String): py = Python.import_module("builtins") for i in range(len(t)): if s[i] != t[i]: result = t[i] print("The difference is:") print(result) break def main(): findTheDifference("abcd", "abced") Link: https://leetcode.com/problems/find-the-difference/description/ ## Benchmarks Time (mean ± σ) Range (min … max) Avg.Memory Runs Python 9.7 ms ± 1.3 ms 7.3 ms … 15.6 ms 8420k 304 runs Mojo 178.0 ms ± 10.9 ms 167.2 ms … 205.7 ms 8500k 14 runs ## Which performed better? The Python code ran 18.31 ± 2.70 times faster than the Mojo code. ### Final Remarks This is the conclusion I came up to after experimenting with both Python and Mojo, from installation up until their usage. - **User Friendly:** For someone like me who doesn't know much about programming languages, I found Python to be more user-friendly. From installing the software to writing code, Python was easier to understand. Installing Python was a simple one-click process, while it took me some time to figure out how to install Mojo, especially because I'm not familiar with terminals and Ubuntu. When it comes to writing code, Python was straightforward and easy to grasp, whereas with Mojo, I had to pay attention to small details to make sure the code worked correctly. So Mojo was harder for me and other new users to adopt and understand - **Easier to Use: **Mojo and Python have similar ways of writing code, so it wasn't too difficult to understand both of them. However, Mojo uses functions from Python, even for simple tasks like "taking input." In Mojo, I had to use a prefix like "py.input" instead of just "input" in Python. This got confusing, and I had to make sure to use the right prefixes for each command, making Python seem simpler and more straightforward. Additionally, a feature I really liked in Mojo was that it explained why an error occurred inside the code. This made it easier for me to figure out exactly what went wrong, which is a feature lacking in Python.As for the REPL, the REPL of Mojo showed the line number for each line of code while Python didn’t. However, I couldn’t use Python-based functions in Mojo when I tried it from REPL. For example when I tried the input function in MOJO, the REPL would stop responding: *While it worked perfectly on Python: * I didn’t do a lot on REPL but when I did, this is what I found. Also, the speed of Mojo was slower even in the REPL. It took longer for Mojo to print a simple “Hello World” than Python. 3. **Performance and Stability:** I noticed a small delay in how quickly the code ran between Python and Mojo. The difference was more noticeable, especially when I coded directly in the terminal instead of using VS Code. So, when it comes to performance, Python is significantly faster than Mojo. The reason **I** believe made Python faster than Mojo was that Mojo needs to import functions from Python for it to use them. So that importing might be the reason for it to run a bit slower while Python uses it’s own function hence the speed difference. In terms of stability, both languages worked well during my usage. However, I did encounter a strange error when I tried to import Python variables inside a function (which is supposed to be done globally, outside the function). Here's an error I faced: *Quite a raw error, considering it mentions LLVM. Maybe it's for the big guys. Regarding stability, I don’t have a solid answer to it. Both of the languages ran smoothly without me having to face bugs or glitches. Overall, I had tonnes of fun and learned a lot about programming languages. I really hope this breakdown helps more noobs on their way to keyboard-breaking glory, and inspires them to try out new tech, specially in its early stages. Peace! ### [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 ### [I feel blue - Unveiling Culture Fit; An Immortal Myth of Recruitment](https://grayhat-company-blog.grayhatstudio.workers.dev/blog/i-feel-blue-unveiling-culture-fit-an-immortal-myth-of-recruitment) - Slug: `i-feel-blue-unveiling-culture-fit-an-immortal-myth-of-recruitment` - Published: 2023-09-15T16:29:00.000+05:00 - Updated: 2025-04-29T00:21:29.000+05:00 - Reading time: 3 min - Tags: Recruitment, Culture Add, Company Culture, Recruitment Strategies, Cultura - Authors: Anonymous - Visibility: public We often find ourselves widening the gyre of recruitment practices in pursuit of filling teams with the *right fit* – hitting all the right notes of skill set, personality, and value. The quest to find *the right fit* to help us grow might as well get us on the path to make-believe land. Apologies for stumping on your bubble there, but as you run towards your familiar rock, you inadvertently overlook the diamond hidden in your path. Culturally-fit hiring strategies have set their roots deep in IT recruitment. It has become a norm to hire individuals matching closely to set organizational values and the JD. It's an unconscious inclination towards structuring the process in ways it benefits the organization *currently*. For a *current* project. To fill *current* needs. Seems like a big win at the moment - and it is! You just achieved culture-fit! But how much value does it add value in the long run? Recruiters go to great lengths to find the right candidate and end up with a conformed team of like-minded – culturally fit individuals. Sounds great, no? But does all the glitter make it gold? *Yes* – would be the easiest deduction. As a recruiter and having been on the sinking boat to hire the right fit, I have hired some exemplary candidates who fit the role and resonated with current culture but alas! I had to face turnover as early as after 2 days of joining (amongst others who stuck around for half a year… or a week). A reflection was in order. A restructuring of the seemingly right process became inevitable. So, who do we really blame here, the recruiter, candidate, or culture? Perhaps leave it to the Gods of fate. Unfortunately, besides being a short-term approach, finding the right people to hire is time consuming and has several downsides! Sometimes, we focus too much on technical skills that the idea of how a person can make the team better is sidelined. There’s a psychological tug-of-war in industry to achieve the *right fit* when all we strive for is to be different – perhaps a *right add *might change the narrative? Make way for the star of this article *culture add* here. We are talking about adding a pop of fuchsia to a canvas of whites. While it may not be everyone's cup of tea, it undeniably commands attention. Similarly, embracing a new perspective, veering away from the conventional, and introducing a challenging feat to the team can kickstart innovation, liberate you from a similarity rut, and broaden your visionary horizons. As Mahatma Gandhi said and I quote, “No culture can live, if it attempts to be exclusive.”. Culture add advocates for diversifying teams with individuals who bring forth a fresh perspective to help the team grow rather than just expand the team who dress, talk, behave, and perform the same. A study conducted by McKinsey & Company highlights the tangible financial benefits associated with top-team diversity. Additionally, research published by The Association for Psychological Science underscores that empirical evidence strongly supports the notion that diversity, encompassing differences in ethnicity, culture, gender, and more, yields substantial advantages for organizations. In a world where everyone races towards a novel future, sometimes the answers lie in the past. Learning from the historical concept of *Seidenstrassen* or Silk Roads; a metaphor of European and Asian cultural interchange, we luminate the pathways not paved with silk and spices, but differences in ideas, perspectives, skills, and traits. The concept of *culture add* or the *right add, *as I have advocated throughout, challenges the traditional notion of recruiting individuals who seamlessly fit into an organization's existing culture. This approach actively encourages the inclusion of culturally diverse individuals within the organization. Ideally, the culture add approach encompasses both cognitive and visible diversity. For instance, from a cognitive standpoint, it might involve hiring an impulsive decision maker into a predominantly calculated team – and vice versa. On a visible level, it could mean adding a female member to a male-dominated group. Building on this, while hiring for IT teams, one can keep an eye out for emerging talent, potential, and disqualify bias based on current skill sets. With the industry growing in all possible directions, hiring for the future is key to thriving in cut-throat competition. Let's ask ourselves, how can this different tech-stack change the dynamics? How might diversifying the skill sets within a team influence the development of creative solutions and products? Will adding this individual with an itch for unconventional into a team of conventional coders stir up innovation? However, this approach doesn’t require an extreme shift from your existing culture. But should definitely inspire a process away from fitting candidates into carefully curated boxes to seamlessly fit-in; and towards an addition to make you think differently, expand your point of view, and invigorate growth in different directions. From hiring with a tunnel vision of stale homogeneity, to striving for dynamic diversity. And that’s where hiring for growth instead of mere expansion begins. Let’s expand more on the topic in the articles in sequel to this one. Share your thoughts, and stay tuned to dive in more detail with us! **Author: **Fatima Majid ### [We built a multiplayer, web-based Mario-like game with PlayroomKit... in 7 days!](https://grayhat-company-blog.grayhatstudio.workers.dev/blog/we-built-a-multiplayer-web-based-mario-like-game-with-playroomkit-in-7-days) - Slug: `we-built-a-multiplayer-web-based-mario-like-game-with-playroomkit-in-7-days` - Published: 2023-08-09T16:51:00.000+05:00 - Updated: 2025-10-12T20:37:37.000+05:00 - Reading time: 5 min - Tags: Multiplayer Gaming, Playroom, PlayroomKit, Gaming, Innovation - Authors: Saad Bazaz, Anonymous - Visibility: public To play the game, open this link on a laptop or TV: https://cast-app.vercel.app/ *Update: *We've now proudly open-sourced this project! Repository: https://github.com/grayhatdevelopers/platformer.ai *“The best articles are the ones with clickbaity titles.” - Unknown* We’ve been grinding our gears for 2 years at Grayhat, trying to get into games. Sure, we love web development and making the best products for our clients. Sure, we’ve built things in low-level vanilla JavaScript (at that point I would’ve loved me some chocolate JS) which haunt me in my sleep every night. But that doesn’t beat the fun in games, does it? We tried everything; Unity. Unreal. ThreeJS (we even tried building a game engine in ThreeJS - more on that later). The toughest part? **Multiplayer**. Every single time. Sure, we got some good, choppy single player working. But when it came to having more people join the fun, the logic just didn’t scale. This year, we made a resolution to try something new. We brushed off the trusty ol’ game engine, Phaser3, and explored some interesting new tech for multiplayer - **PlayroomKit.** *(I mean, we’re not biased towards it. There are a lot of great solutions out there - it’s just that this is the one we helped build.)* It’s not really something new unless we give ourselves an insane challenge, is it? So here goes… A multiplayer Mario-like game in 7 days. 7. *Multiplayer.* ## Day 1 - Inception: *“We’ll have to start by building a Mario-like game.”* *“Last I heard, my job title wasn’t ‘Wheel Inventor’. Let’s try something else...”* We usually build upon the shoulders of giants, and this time was no different. We found some cool code for Mario in Phaser3 on GitHub. The code comments were in Chinese, so it took some translation with ChatGPT to understand what it meant. We studied the refreshingly-nice documentation for PlayroomKit. Given that our objective was a classic platformer game, the Phaser example gave us a good high-level overview of how the game would work. PlayroomKit's Stream Mode makes your game act like a typical game console - A separate screen plays the game, while the phone(s) are simply controllers. We found that was a nice option for our Mario game, since the classic feel of the NES is really hard to replicate on a phone’s tiny 5” screen. ## Day 2 - Masters of Puppets We ran the project, and fell into the classic dilemma. As a software engineer, it feels easier to rebuild a project from scratch because it makes the code feel more like you. That keeps you safe and comfortable. I feel like the sign of a good software engineer is their ability to play with the cards they get and make the best out of it. I think of it as *iterative rebuilding* - use the right practices *going forward*, and *refactor* things which get in your way. Sort of like a long antibiotics course. In our case, the code structure was great - but to actually have the player move whenever the controller on PlayroomKit was moved, we thought we might have to dive deep into the game logic. Fortunately for us, we had a short brainfart - We could simply **simulate keypresses **within the game. I knew for a fact that game engines had such options, to account for bot players, and for automated testing. I’d seen a similar concept being used in Google’s own blogs, where they simulated keypresses on Chrome’s Dino Game. So we created a basic Phaser KeySimulator, and hooked it up with our phone controller: // Simulate pressing a key simulateKeyPress(keyCode) { const keyObj = this.input.keyboard.addKey(keyCode) keyObj.isDown = true keyObj.timeDown = this.time.now keyObj.isUp = false keyObj.timeUp = 0 this.input.keyboard.emit('keydown') } // Simulate releasing a key simulateKeyRelease(keyCode) { const keyObj = this.input.keyboard.addKey(keyCode) keyObj.isDown = false keyObj.timeDown = 0 keyObj.isUp = true keyObj.timeUp = this.time.now this.input.keyboard.emit('keyup') } // An example of simulating the UP key for 1 second simulateKeyPress(Phaser.Input.Keyboard.KeyCodes.UP) setTimeout(() => simulateKeyRelease(Phaser.Input.Keyboard.KeyCodes.UP, 1000)That was it. No need to change controls deep down - We just puppeteered it from the top! ## Day 3 - Powering Up We whipped up a simple SNES controller using some great code from Codepen. We hooked the buttons with PlayroomKit’s state logic and started sending “inputs” from the controller to the cast screen. See the Pen SNES Controller by Tim Pietrusky (@TimPietrusky) on CodePen. So far, we’d gotten single-player to work. Game running on laptop, controller running on phone. *Some problems: 1. It was only single-player. 2. We had no way to automate testing. We had to play the game every single time to test every feature. ## Day 4 - Luigi: Our idea was to have a free-for-all of players filling the game, to test the limits of the PlayroomKit SDK. The original game’s code didn’t agree - it was built solely for a single player. ### Hardcoding: The first step to a good experiment is dummy data - you can’t tightly couple yourself in long implementations unless you know what you’re doing. In our case, it meant adding a second hardcoded player. After some blood, sweat and tears, and adding comments wherever we broke stuff, we were able to add a second, albeit quite diseased, player to the game, and make it perform actions based on a second player (also hardcoded). ## Day 5 - Multiplayer Mayhem: If it works for 2, it should work for 20. We took a dive and replaced the hardcoded second player with some more generic logic which allowed an “array” of players to exist simultaneously, each with its own logic. This took multiple breaks of the code and a lot of overtime, but the results? Worth it. *## Day 6 - Field Test: It was time to put the guinea pigs up to the test. *The chaos which ensued was exactly what we were looking for. ## Day 7 - Deployment We decided we’d had enough of juggling two repositories - one for the cast screen in Phaser3, the other for the controller in React - so we built a Turbo monorepo to make things easier to deploy, manage and test. Installation was pretty straightforward - until we got the genius idea to standardise Node versions across the two projects. There went our day. Vercel’s got great support for Turborepo, so deployment was a breeze. ## A noob's overview Making games multiplayer has always been a hassle, and it's a huge barrier-to-entry for emerging game devs and studios. For Grayhat, PlayroomKit was the key for a rag-tag group of web developers to explore game dev at warp speeds - no need to worry about infra anymore, we could now focus on making games look appealing and engaging. That's the whole point. Apps can survive bad UI/UX to a certain extent. Games can't. If your game isn't fun, no one is going to even consider it twice. But that kind of craft takes time, and when you're spending hours figuring out why your networking code is sending corrupt data, you're either gonna spend big bucks, or a lot of hours. We have neither. Sure, PlayroomKit has its pitfalls - there's a huge roadmap ahead with tonnes of work to be done. But I understand that it's early stage tech and there's a lot of potential in it. The Playroom team already has a huge list of amazing features, like built-in lobbies and joysticks, and we love being part of the journey. I'd put it as simply as: **It's the Firebase of game development.## Parting words 🚀 Have you tried game dev? What are the challenges you've faced? Would you like to read more about stuff like this? DROP A COMMENT! *Disclaimer:* We do not own the rights over any characters or any resemblance of the characters depicted in the game. This experiment was purely for fun and to learn, and we do not have any commercial benefit from it. ### [Medusa.js for Entrepreneurs, Part 2: Features](https://grayhat-company-blog.grayhatstudio.workers.dev/blog/medusa-js-for-entrepreneurs-part-2-features) - Slug: `medusa-js-for-entrepreneurs-part-2-features` - Published: 2023-06-14T17:06:00.000+05:00 - Updated: 2024-05-09T17:07:12.000+05:00 - Reading time: 3 min - Tags: E-Commerce, Medusa, Medusa.js, JavaScript - Authors: Anonymous - Visibility: public *Cloning the frontend, backend, and admin panel repositories results in a readily available template e-commerce application with all the basic user flows, from adding a product to a basket to placing and tracking orders. Furthermore, the administration panel has every capability imaginable for a template application. Below is a brief description of all the major features ready to use in the Medusa template app: ### **User Side (Frontend)** Below are some of the prominent features readily available for end-users on the frontend. Being open source, Medusa is evolving day by day and continuously adding new features to make e-commerce application creation a breeze! **Login/Sign up:** Users can create accounts, and Medusa keeps track of completed orders, pending orders, billing addresses, and more. **Note:** Account creation is not mandatory; users may also make anonymous purchases without signing in. **Browse products: ** Users can explore different available products and view specific details for each product, such as variants, material, weight, kind, shipping and returns, inventory, and other product details provided by the admin. **Add to cart: ** Users can easily add products to their cart and set the desired quantity. Medusa also handles the inventory quantity, which we'll cover later in the admin section! **Discount coupon: ** Users can apply a discount coupon, if offered by the store, and enjoy discounts on price or delivery based on the conditions set by the admin. **Gift card: ** Users may enter a gift card, if applicable, and receive rewards for their purchase according to the conditions set by the store admin. **Delivery:** Users can select shipping alternatives provided by the store manager after completing the billing details form. **Payment: ** Once products are added to the cart, the delivery method is selected, discounts (if any) are applied, and taxes (if any) are added, users can make payments using authorized methods set by the store administrator. However, integration of the payment plugin is required before proceeding. **Receipt generation: ** After a successful payment, an order receipt is generated, and the order is placed on the server and displayed on the admin dashboard. All basic template pages are available on the frontend; simply customize them as desired and create any new pages related to your app that are not already available. ### **Admin Panel** Logging into the Admin Panel using the default account (username: admin@medusa-test.com, password: supersecret) or an admin account created by posting an API request on the server using Postman gives you access to the following ready-to-use features. **Orders: ** When an order is placed, it is added to the orders list on the orders tab at the top of the admin dashboard. Clicking on an order displays detailed information about the placed order and provides admin access to available options, such as canceling the order, capturing money, creating fulfillment, editing the order, and more. **Products: ** One of the most important modules of any e-commerce platform is the ability for the admin to add new products to one or more sales channels (sales channels will be addressed later). Medusa provides full admin support for adding/editing products, organizing products, adding products to different sales channels, adding different variants with different prices, adding attributes related to products, adding thumbnails and media files (requires integration of a cloud bucket plugin), setting inventory management flags, monitoring quantity, defining delivery alternatives, and much more for adding items as per the store management requirements. **Customers: ** All clients registered with the application can be viewed and searched in the customer list displayed in the customers tab of the side menu bar. Registration date, orders, and other client information can be accessed here. Admin can also add new customers. A highly interesting and necessary feature in the customers module is the ability for the administrator to establish and add customers to customer groups. Customers in a certain group can be readily treated based on specific conditions/benefits, such as creating a group of B2B customers or loyal customers, etc. These clients can be linked to one or more sales channels, allowing for offering different options to target audiences or charging varying prices for the same items. **Discounts: ** Discounts can be suggested for all customers as a whole or for a specific consumer group. Medusa offers three types of discounts: percentage discounts, flat amount discounts, and free delivery discounts. When a discount is created, a discount code must be generated for eligible users to enter and receive the discount. **Gift cards: ** Gift cards can be generated and managed by the store manager or used by customers for their purchases. **Pricing: ** Prices for different product variants can be overridden for different customer groups. If no override is made, then the default product variant price will be applied. These are the major features of the Medusa Admin Panel. Furthermore, Medusa provides support for managing regions, currencies, return reasons, and taxes for different regions, while also allowing the creation of different sales channels (still in beta version and needs to be enabled before use at the time of writing the blog). ### **Conclusion** Everything you need for your e-commerce application is available; all you have to do is customize it to your specifications and get paid for the whole e-commerce solution in the shortest time known to humanity! Article by Talha Rizwan Malik ### [Medusa.js for entrepreneurs, Part 1: Intro](https://grayhat-company-blog.grayhatstudio.workers.dev/blog/medusa-js-for-entrepreneurs-part-1-intro) - Slug: `medusa-js-for-entrepreneurs-part-1-intro` - Published: 2023-06-06T17:08:00.000+05:00 - Updated: 2024-05-09T17:09:02.000+05:00 - Reading time: 2 min - Tags: Medusa, Medusa.js, JavaScript, E-Commerce - Authors: Anonymous - Visibility: public *The world of e-commerce is experiencing unprecedented growth, with more businesses moving online each day to meet the demands of digital consumers. As the industry continues to evolve, the need for efficient, user-friendly, and powerful tools for creating e-commerce web applications has become more critical than ever. Enter MedusaJS: a powerful, open-source e-commerce platform that simplifies the process of building and managing an online store. In this blog, we'll explore the power of MedusaJS and how it makes creating an e-commerce web application a breeze for developers. **1. Ready-to-Use Application:** Everything you need for your e-commerce application is available, from the frontend to the backend and the admin panel. With all the necessary modules at your disposal, your task is to mold it according to your requirements and create an e-commerce application with minimal coding in the quickest time possible. **2. Flexible and Modular Architecture:** One of the standout features of MedusaJS is its flexible and modular architecture. This allows developers to easily tailor the platform to their specific needs by adding or removing features as necessary. The use of a headless architecture also enables seamless integration with any frontend, making it an ideal choice for businesses seeking a custom online shopping experience. **3. Easy-to-Use API:** MedusaJS provides a robust, easy-to-use API that allows developers to access and manage all aspects of their e-commerce store. With comprehensive documentation and an active community, getting started with MedusaJS is simple. Developers can quickly build and deploy their e-commerce web applications with ease. **4. Support for Multiple Payment and Shipping Options:** An essential aspect of any e-commerce platform is its ability to support multiple payment and shipping options. MedusaJS offers built-in support for popular payment gateways like Stripe, PayPal, and Braintree, as well as integrations with shipping providers such as Shippo and EasyPost. This flexibility allows businesses to choose the payment and shipping options that best suit their needs, ultimately enhancing the customer experience. **5. Extendable with Plugins:** MedusaJS's plugin-based system enables developers to extend the platform's functionality with ease. Numerous plugins are already available for various use cases, such as adding support for additional payment gateways or integrating with third-party services. This extensibility ensures that MedusaJS can grow and adapt to meet the ever-changing needs of the e-commerce landscape. **6. Community and Support:** As an open-source platform, MedusaJS boasts an active and supportive community of developers and users. Help is readily available through forums, social media, and other online resources. Regular updates and improvements to the platform ensure that it remains at the cutting edge of e-commerce technology. **Conclusion:** MedusaJS is a powerful, flexible, and easy-to-use e-commerce platform that streamlines the process of creating and managing an online store. With its modular architecture, robust API, support for multiple payment and shipping options, and a thriving community, MedusaJS is an excellent choice for businesses looking to build a custom e-commerce web application. By harnessing the power of MedusaJS, developers can focus on creating engaging, feature-rich online shopping experiences that cater to the demands of today's digital consumers. Article by Talha Rizwan Malik