All blog posts:
Why is boarding a plane still a mess?
Read original post5/9/2025
Boarding an airplane often feels like a chaotic race to secure overhead space and window/aisle seats. You’d think after decades of flying, we’d have figured this out.
Boarding an airplane often feels like a chaotic race to secure overhead space and window/aisle seats. You’d think after decades of flying, we’d have figured this out.
What makes boarding so messy?
- Airlines want fast turnarounds.
- Planes are badly designed for boarding — narrow aisles, one door, limited bins.
- We are (kinda) selfish – We want our seat and bin space over the "greater good."
- Add in families, loyalty programs, and a recipe for a mess.
How are airlines trying to fix this logistical puzzle?
Airlines typically use back-to-front boarding – moving passengers through the cabin from back to front. Pre-cabin (passengers with disabilities, families with young kids, etc) and loyalty members are given priority to board first. Then comes the main cabin, usually from the back of the plane to the front.
Most popular methods:
Back-to-front
The last rows of the plane are boarded first, followed by the first rows.
Pros: More money for airlines selling front tickets for premium.
Cons: Often slow due to the crowding of aisles.
Window-Middle-Aisle
Window seats are boarded first, followed by middle seats, and finally, aisle seats. This method can be further optimized by combining it with the Back-to-front method.
Pros: Spreads passengers, reducing bunching.
Cons: Limited flexibility if a passenger misses their group.
Open Seating (e.g. Southwest)
Passengers can choose any available seat.
Pros: Often touted as the fastest seating method. Passengers can choose preferred seats.
Cons: Early boarders snag window or aisle seats, including overhead space.
Random with assigned seats (e.g. Ryanair)
Board in no particular order, but have pre-assigned seats.
Pros: Faster than Back-To-Front.
Cons: Can feel chaotic.
Rotating zone
Alternate between the front and back of the airplane. First five rows, followed by last five rows, etc.
Pros: Less congestion.
Cons: Can be confusing for passengers.
New/Proposed methods:
Steffen
Window-Middle-Aisle approach combined with alternates between odd-numbered and even-numbered seats.
Pros: Spreads passengers among rows, allowing efficient bin access.
Cons: Complex, logistically challenging.
Reverse pyramid (modified)
Window seats in the back, followed by window seats in the front. Then, middle seats in the back, followed by middle seats in the front. Finally, aisle seats in the back, followed by aisle seats in the front.
Pros: Spreads out passengers.
Cons: Complex.
But nothing works?
Human factors such as seat preferences, mobility issues, and passenger behavior can all slow down the boarding process. Aircraft design factors like narrow aisles, limited bin space, and a single door create bottlenecks, further complicating the boarding process. Finally, airplane policies (e.g. early boarding perks) and airlines prioritizing quick turnarounds further contribute to this puzzle.
The Real Deal
At the end of the day, this isn’t just a math problem you can solve with a clever algorithm. And the boarding puzzle isn't a math problem - it's a human one. The chaos isn't just poor planning - it's the result of a game where we are all trying to win our little game. And until planes, policies, or people change, we’ll keep scrambling.
Recreating Breakout Game in JavaScript
Read original post4/2/2025
Breakout is an arcade game where the player moves a paddle to bounce a ball and break bricks. It was made popular by Atari and later inspired multiple classics such as Space Invaders and Brick Breakers.
Last week, I thought of creating this game from scratch. The goal was to leverage the power of Three.js to explore physical simulations.
Setting up:
I started with a simple React project and installed two libraries - react-three/fiber and react-three/cannon.
- react-three/fiber is a renderer for three.js, simplifying 3D scene management.
- react-three/cannon provides hooks for cannon.js, a physics engine for realistic collisions.
The structure is fairly standard, with Physics from cannon wrapping our game area.
Canvas
- Physics
---- GameControls
---- Paddle
---- Ball
---- Bricks
- Physics
Canvas
Components
The Ball, Paddle, and Wall components form the core of the game, using Cannon.js’s useSphere
for the ball’s dynamic physics, useBox
for the paddle and walls’ static collision boxes, and Three.js’s meshPhysicalMaterial
to give the paddle a polished, rounded 3D appearance.
The ParticleEffect component adds visual flair by generating fading particles at broken brick positions using Three.js’s useFrame
, while Clouds component creates a subtle, low-poly background with randomized positions and scales, optimized with useMemo
and frustumCulled
for performance.
Collision handling - Wall:
- Top wall - Invert y-velocity to bounce the ball downward.
- Side wall - Invert x-velocity to bounce the ball sideways.
- Bottom wall - Stop the ball, disable physics and triggers the game-over state.
- Nudge - Add a small x-velocity for side walls to prevent the ball from getting stuck in repetitive patterns.
Collision handling - Brick:
- Create a random bounce angle within a 60° cone (±30° from straight up 0°)
- Apply a cooldown period to prevent multiple rapid Collisions.
- Generate a random angle and apply a slight downward bias (prevent purely horizontal bounces).
Collision handling - Paddle:
- Calculate bounce angle based on where the ball hits the paddle (-1 for left edge to 1 for right edge).
- Avoid near perfect vertical bounce by ensuring minimumBounceAngle.
- Add a small random angle variation (1° to 2°) to prevent predictable bounces.
//Paddle hit
let bounceAngle = impactPosition * maxBounceAngle;
bounceAngle = Math.sign(bounceAngle) * Math.max(minBounceAngle, Math.abs(bounceAngle));
const randomVariation = (Math.random() * (2 - 1) + 1) * (Math.PI / 180) * (Math.random() < 0.5 ? 1 : -1);
bounceAngle += randomVariation;
Final thoughts
This was a challenging project, mostly because of issues with the ball getting stuck. It's fair to say most of the effort went into fine-tuning bounce logic: on bounces, adjusting angles and adding random variations to introduce slight unpredictability to the game.
Another key focus was performance - it was easy to get this game stuck in a re-rendering loop. Using frustumCulled, useMemo to optimize resource usage and redundant calculations are essential to balance visual quality without overloading the browser.
Basketball is a solved sport
Read original post2/1/2025
Basketball has evolved from a game of unpredictability into a game of calculated decision-making with the use of data and analytics. From a game of points, assists, and rebounds, it has progressed into using thousands of data points to optimize every element of the game.
Basketball has evolved from a game of unpredictability into a game of calculated decision-making with the use of data and analytics. From a game of points, assists, and rebounds, it has progressed into using thousands of data points to optimize every element of the game.
All decisions are made based on numbers not intuition. Long-range shooting and layups are preferred over mid-range shooting. Players are no longer do-it-alls; they are now given specialized roles.
Three-point rain
In the last decade, long-range shooting has gone from a secondary option to a primary choice for building offense. Recently, teams have realized three-pointers have higher point value despite their lower scoring percentage. This has led to a revolution in structuring an offense around taking long-range shots. The Golden State Warriors, led by Stephen Curry, probably jump-started this trend with 34 three-pointer attempts per game in the 2018-19 season, twice as much from five years ago. Celtics, this season, have averaged almost 50 three-pointers attempt this season (2024-25 season).
In the past, the team built its roster around a big name like Shaq. Most of the offense were from the center. This has now changed, with the primary strategy being to stretch the opposition and take long-range shots.
Rise of 3-and-D model
The 3-and-D model refers to a player, usually a wing player, who is just above average at three-pointers and plays competent defense. Forget about positions; just get a guy who can do some 3s and Ds.
Danny Green is probably the father of this model, with his 40% career three-point field goal percentage and he also made into all-defensive team.
In recent years, every team has had at least one 3-and-D model player on the roster.
Specialization
Gone are the days of an all-around player. There is no longer a need for a player who does everything. Look at players like Kobe Bryant and Lebron James (early career); they not only scored but guarded defense, caught rebounds and played the role of playmakers.
Now, it’s all about creating lineups with specialized players. A team typically consists of a three-point shooter, a defensive specialist, a playmaker, and rebounders. They all have specific roles assigned to them.
Technology
A catch-all word for statistics, technology has played a pivotal role in shaping this game.
In addition to data collection, biomechanics and motion cameras track every player’s movement. NBA even brought SportVU from football; it follows the ball and supposedly captures images 25 times per second. Coaches can now use this to analyze the speed, position, form, and motion of each player on the court.
In the end, it’s all about optimizing every ball possession.
What now?
Basketball might have lost its flair; every move is now predictable and measured. What is the future of basketball, is anyone’s guess? Maybe a rule change is around the corner?
Atomics in Javascript
Read original post1/20/2024
Atomics object ensures indivisible operations, avoiding concurrency bugs.
tldr; Atomics object ensures indivisible operations, avoiding concurrency bugs.
Before we dive into Atomics, we need to understand SharedArrayBuffer. SharedArrayBuffer
is a fixed-length raw buffer that can be shared between threads. Unlike ArrayBuffer
, it can be shared across threads, requiring us to think about race conditions.
Atomic methods (such as add, store) makes sure operations on SharedArrayBuffer
are indivisible, preventing race conditions in multi-threaded environments, guaranting atomicity.
In the above snippet, Atomics.add
ensures both increment apply, always logging 2.
Note: Without proper headers (e.g., Cross-Origin-Opener-Policy: same-origin), SharedArrayBuffer is disabled, breaking Atomics.
Sychronize with wait and notify
Atomics.wait
pauses a thread until Atomics.notify
wakes it, giving us Linux-like synchronization. The nuance here is wait requires exact value.
Bitwise operations - or, xor and and.
Setting bits to 1 if currentValue and value are 1 (and), if exactly one value is 1 (xor), if either is 1 (or).
arr[0] = 5
is 0101 (8 bit representation for Uint8Array. Similarly, 2 is 0010.
Atomics.or(arr, 0, 2)
performs OR between current value 0101 and input value 0010.
Position 1: 0 | 0 = 0
Position 2: 1 | 0 = 1
Position 3: 0 | 1 = 1
Position 4: 1 | 0 = 1
Result: 0111 (decimal 7).
Result 7 is stored in the array, but the method returns 5 (old value).
Usage:
Atomics
object is handy when dealing with shared buffers like canvas animations or synchronizing states in multiplayer games. Also, it can be used to offload some heavy tasks like image processing.
Here is an example scenario:
Two counters increment randomly, One worker waits for the counter to reach a threshold before resetting it, using Atomics.wait
. The main thread updates the UI with the counter's value, polled via Atomics.load
.
Final thoughts:
Atomic operations can seem complex and daunting, especially with a simpler alternative - PostMessage
where data can be shared among threads by sending messages. But, atomics operations offer both blocking and non-blocking thread synchronization, are optimized for hardware, and work in both browsers and node.js (with worker_threads).
It opens a portal to a multi-threaded powerhouse, giving us an ability to build thread-safe and high-performance applications.
Try/Catch/Finally in JavaScript
Read original post5/23/2023
Try this? Caught something? Finally, do this!
tldr; Try this? Caught something? Finally, do this!
try/catch/finally is a Javascript construct to handle errors. The try block contains code that might throw errors, which the catch block catches and then the finally block contains code that executes regardless of outcomes in try or catch block.
It is helpful when making API calls, hiding progres bars/spinners, logging operations, resetting UI states, resource cleanup and other things.
Sample usage:
Note: finally always executes (regardless of try/catch block or return/throw/break statements.
But why not keep the finally block code outside?
Answer is the finally block is tied to try/catch to ensure it runs after try/catch. Code after try/catch runs only if uncaught errors propogate. In case of finally, it runs even if an error is thrown or caught.
The following code snippet shows this.
So far, so good, this seems helful. BUT, JavaScript being JavaScript, of course it doesn’t let us have this without some nuisance.
return in finally overrides try/catch
return in try executes finally first
throw in finally overrides try/catch errors
finally runs even for uncaught errors
finally can modify variables (but return is not affected unless finally explicitiy returns)
finally supresses error if returned
Final thoughts:
The Javascript engine maintains a stack frame for try, throws error to catch, and guarantees finally execution despite the change in return flow. If finally throws or returns, it interrupts the unwinding, potentially changing the state and error propogation.
Despite these flaws, try/catch/finally is indispensable for error handling and deterministic cleanup. There are alternatives though. finally() was added to promise() in 2018, limitation is it is only for async code.
fetch(url)
.then(response => response.json())
.catch(error => console.error(error))
.finally(() => console.log('Done'));
For now, I will continue using try/finally/catch while being mindful of its flaws.
Is there such a thing as random?
Read original post2/23/2022
Is randomness just a fancy word for saying we don't have all the information? Can everything in the universe be boiled down to cause and effect? Or is it possible for an uncaused cause to exist?
Is randomness just a fancy word for saying we don't have all the information? Can everything in the universe be boiled down to cause and effect? Or is it possible for an uncaused cause to exist?
Randomness is defined as the absence of structure or pattern. It's when effects occur that cannot be traced to any cause. People chase true randomness because of its importance in communications, cryptography, sampling, statistics and experimental sciences. It's the holy grail for secure communication and unbiased results.
Take an example of rolling a die. The outcome depends on several factors: the die's mass and shape, the initial position of the die, the speed and angle at which it is thrown, the texture of the surface, etc. Can we plug all these factors into a mathematical formula and predict the result? Difficult, yes; impossible, no. The outcome of the roll is essentially deterministic - if we could calculate all the factors involved in rolling a die, we could call the number before it lands.
Here's the thing: humans aren't good at being random. Our brains are wired to create, spot, and think in patterns. Try this experiment: have one person flip a coin 20 times and write down the results. Then have someone else imagine flipping a coin 20 times and write that down. Compare the lists, and we will spot the fake one instantly. The person making it up will avoid long streaks, like five tails in a row, because it doesn't 'feel' random. But true randomness doesn't care about what happened. It doesn't have a memory of previous flips, and long chains can happen.
Computers aren't much better. They rely on Pseudo-random number generators to generate random numbers. Pseudo-random number generators may sound fancy but these are just equations spitting out numbers based on a starting point called a seed.
This lack of true randomness is a problem. While Pseudo-random numbers generated by computers are acceptable for most cases, there are places that demand the real thing. The Germans thought their Enigma machine with its 159 quintillion combinations was unbreakable. It wasn't. Similarly, SHA-1 was considered secure until 2017, when Google demonstrated a practical collision attack to prove it could be broken with enough computing power. The WEP protocol for Wi-Fi encryption was cracked in 2001 because its key generation wasn't random enough. Randomness isn't just a nerdy concept, it's critical for secure communication, sampling and even understanding evolution.
So where do we get true randomness from? Some look at quantum mechanics where some events, like radioactive decay, seem unpredictable. But, still, we are not certain if it's truly random or just too complex for us to crack. The jury's still out on whether the universe allows for pure, uncaused randomness.
Deep down, everything in the universe seems to follow some kind of pattern. We might not understand it completely, but we can't deny there isn't one. Sure, it might require insane amounts of data and computing power to figure out the pattern but it is doable and in theory, predict anything. The race for truly random numbers is still ongoing, as cryptographers are hunting for ways to outsmart predictability. Until then, randomness might just be our name for the gaps in what we know.
React and TypeScript cheatsheet
Read original post1/2/2022
A cheatsheet to write better React with TypeScript
A cheatsheet to write React with TypeScript
This tutorial assumes you have the setup done with the usuals, such as ts-node and @types/react. If not, check out Setting up React with TypeScript before we continue.
Before we get started, we need to settle the usual debate between types and interface. The general rule of thumb is use type for states and props and interface for everything else.
Off we go.
1. Components:
Function Components
Class Components
Pure Components
Pure components doesn't re-render if parent component changes, it shallow compares state and props of its own component.
With state and props
Must pass arguments to the functions.
2. Events:
3. Hooks:
Could also pass boolean value if state is boolean.
create-ref always returns a new ref while use-ref is persistent across multiple renders in a functional component.
4. Props:
With componentProps we can extract the props of an element. This is useful when working with third-party library which doesn't expose you their props.
Extract it.
extend it.
or type-check them.
4. Context:
Context allows you to pass props to another component without having to pass through components.
Setting up react with Typescript from scratch
Read original post1/1/2022
This is a seed project on React with Typescript that I use for the majority of my projects.
This is a seed project on React with Typescript that I use for the majority of my projects.
As a veteran software engineer, I generally don't like using tools such as create-react-app. I prefer to create my project from scratch and want control over each of the tools and configuration files. As the web development industry changes, with cool things being created each day, I keep my seed projects up-to-date and stable so they can easily be cloned for rapid development.
At a glance
Markup (HTML) | JSX (React 18) |
Script | Typescript/React |
Styling (CSS) | Tailwind |
Build | Webpack 5/Terser |
Unit Test | Jest/Testing library |
Code quality/Linting: | Eslint |
Step 1: Create project and install basic packages
We will start by creating a directory and initialize npm.
This creates package.json. Let's add some packages.@types/* are type declaration pacakges. testing-library is one of the popular testing packages out there for React. ts-node is the typescript exection engine for Node.
Time to create typescript configuration file.
Step 2: Setup webpack and react
We'll start by creating webpack configuration file - webpack.config.ts
style-loader extracts css and injects them to head element in a html document. css-loader resolves the dependencies such as import and url. postcss-loader makes css cool with linting, vendor prefix etc.
Create entry file - index.jsx
Since React 18, createRoot is used instead of render API.
Setup tailwind config file - tailwind.config.ts
Tailwind is kinda similar to bootstrap with its utility classes. But it doesn't provide classes for components like buttons and error messages.
Enable tailwind - tailwind.config.ts
Add HTML file - index.html
bundle.js is our bundled file (output).
Step 3: Add test
Add Test - jest.config.ts
Our jsx needs babel processing.
Create file - setupTest.ts
jest-dom extends dom with methods such as toContainHTML, toHaveClass etc.
Step 4: Setup ESLint and finishing touches.
Create eslint configuration - .eslintrc.json
We'll use the popular airbnb styleguide - eslint-config-airbnb-typescript for our application. Package:
Update scripts in package.json
Step 5: Running the app.
npm run dev should start our dev server, npm run jest should start our unit test etc.
Extracting realtime data from ThinkOrSwim
Read original post1/1/2022
In Windows, applications can expose their internal functions/data as COM objects called ROM automation. Then, Excel can tap into these interfaces using the RTD (Real Time Data) feature.
In Windows, applications can expose their internal functions/data as COM objects called ROM automation. Then, Excel can tap into these interfaces using the RTD (Real Time Data) feature.
A standard synrax to get data from a RTD server looks like:
A popular trading platform, ThinkOrSwim, supports this feature by creating a COM server (IRTDServer) from which Excel can hook into and receive live data.
Custom RTD client
We can quickly implement a program to hook into this interface and get data without needing for Excel.
Use GUID to create a reference to a specific COM server instance. Use ConnectData method to connect to a specific topic and get data.
Calculating pie in javascript
Read original post6/30/2015
Pi is one of the most fascinating numbers in mathematics due to its irrational and transcendental nature.
Pi is one of the most fascinating numbers in mathematics due to its irrational and transcendental nature. The simplest calculation of 'pi' is to draw a circle and measure the ratio of the diameter and the circumference which gives us 2-5 decimal digits at best. Although, it may be enough for most practical purposes, calculating digits of pi has been seen as a challenge.
In recent years PIE has been calculated to 130 trilion digits
There are many formulas for computing the value of 'pi'. The most famous of this is 'Machin's formula'.
Once we have the arctan value, rest is just simple arithmetic.
This code is based on Ken ward's work and also of Pascal Sebah
Posted on July 30, 2015
Altmel Gpu
Read original post1/1/2013
This is a GPU made with Atlmel AT90S2313. It can be programmed using computer with a printer cable or a USBasp device.
This is a GPU made with Atlmel AT90S2313. It can be programmed using computer with a printer cable or a USBasp device.
With a 4Mhz oscillator and some resistors, it is possible to create a signal on its PB0 and PB1 pins. With a voltage divider and a resistor ladder, those signals can be converted to a composite video signal.
The encoding is done with two resistors: 1Kohm and 470Ohm, which is connected to a 1uF capacitor. The signal is as follows: 0.3V for black, 0.7Volt for gray and 1V for white.
Download Hex code from here (atmelbars.hex)
A typical video signal varies from 0V to 1V.
Like the chart above, I have the signal as follows: 11 for white, 01 for black, 10, for gray.
You can use any programmer (Khazama AVR programmer, ALTMEL command line programmer, AVRfreaks programmer etc), I personallly liked Khazama programmer for its simplicity. The program is simple, you want a set of binary number on any of the PB ports. I have used two resistors 1Kohm and 470 Ohm to stablize the voltage.
8 Bit gpu
Read original post1/1/2013
This is a 8 bit GPU made entirely of TTL chips. It can convert any sequence of binary numbers to a composite video signal.
This is a 8 bit GPU made entirely of TTL chips. It can convert any sequence of binary numbers to a composite video signal.
It consists of 10 8-bit comparators connected to the counter for keeping track of various signals. They are encoded with various gates like AND, NOR and OR
This is a 8 bit GPU made entirely of TTL chips. It can convert any sequence of binary numbers to a composite video signal. It consists of 10 8-bit comparators connected to the counter for keeping track of various signals. They are encoded with various gates like AND, NOR and OR.A typical video signal varies from 0V to 1V. The 0V is one horizontal/vertical sync pulse.
With the comparator constantly giving the signal on lines, screen and pulses, we can add a RAM and a MUX. The 8 bit output from RAM can be feeded to MUX which gives each bit one by one. We now have a waveform of bits.
Now, we need to make a digital to video converter. I have used a three state buffer to activate three different signals: 11 for white, 01 for black, 10, for gray. With the voltage divider and resistor ladder I stabilized the voltage to 0.3V for black, 0.7Volt for gray and 1V for white.
With an EPROM and a RAM, it is possible to draw (almost) anything on TV.
Check out the rough schematic. (I will add complete schematics and instructions soon!)
The schematic is missing all the logic gates and an oscillator.
Special thanks to Jack Eisenmann