10 interesting stories served every morning and every evening.




1 777 shares, 86 trendiness

21 Lessons From 14 Years at Google

When I joined Google ~14 years ago, I thought the job was about writ­ing great code. I was partly right. But the longer I’ve stayed, the more I’ve re­al­ized that the en­gi­neers who thrive aren’t nec­es­sar­ily the best pro­gram­mers - they’re the ones who’ve fig­ured out how to nav­i­gate every­thing around the code: the peo­ple, the pol­i­tics, the align­ment, the am­bi­gu­ity.

These lessons are what I wish I’d known ear­lier. Some would have saved me months of frus­tra­tion. Others took years to fully un­der­stand. None of them are about spe­cific tech­nolo­gies - those change too fast to mat­ter. They’re about the pat­terns that keep show­ing up, pro­ject af­ter pro­ject, team af­ter team.

I’m shar­ing them be­cause I’ve ben­e­fited enor­mously from en­gi­neers who did the same for me. Consider this my at­tempt to pay it for­ward.

It’s se­duc­tive to fall in love with a tech­nol­ogy and go look­ing for places to ap­ply it. I’ve done it. Everyone has. But the en­gi­neers who cre­ate the most value work back­wards: they be­come ob­sessed with un­der­stand­ing user prob­lems deeply, and let so­lu­tions emerge from that un­der­stand­ing.

User ob­ses­sion means spend­ing time in sup­port tick­ets, talk­ing to users, watch­ing users strug­gle, ask­ing why” un­til you hit bedrock. The en­gi­neer who truly un­der­stands the prob­lem of­ten finds that the el­e­gant so­lu­tion is sim­pler than any­one ex­pected.

The en­gi­neer who starts with a so­lu­tion tends to build com­plex­ity in search of a jus­ti­fi­ca­tion.

You can win every tech­ni­cal ar­gu­ment and lose the pro­ject. I’ve watched bril­liant en­gi­neers ac­crue silent re­sent­ment by al­ways be­ing the smartest per­son in the room. The cost shows up later as mysterious ex­e­cu­tion is­sues” and strange re­sis­tance.”

The skill is­n’t be­ing right. It’s en­ter­ing dis­cus­sions to align on the prob­lem, cre­at­ing space for oth­ers, and re­main­ing skep­ti­cal of your own cer­tainty.

Strong opin­ions, weakly held - not be­cause you lack con­vic­tion, but be­cause de­ci­sions made un­der un­cer­tainty should­n’t be welded to iden­tity.

The quest for per­fec­tion is par­a­lyz­ing. I’ve watched en­gi­neers spend weeks de­bat­ing the ideal ar­chi­tec­ture for some­thing they’ve never built. The per­fect so­lu­tion rarely emerges from thought alone - it emerges from con­tact with re­al­ity. AI can in many ways help here.

First do it, then do it right, then do it bet­ter. Get the ugly pro­to­type in front of users. Write the messy first draft of the de­sign doc. Ship the MVP that em­bar­rasses you slightly. You’ll learn more from one week of real feed­back than a month of the­o­ret­i­cal de­bate.

The in­stinct to write clever code is al­most uni­ver­sal among en­gi­neers. It feels like proof of com­pe­tence.

But soft­ware en­gi­neer­ing is what hap­pens when you add time and other pro­gram­mers. In that en­vi­ron­ment, clar­ity is­n’t a style pref­er­ence - it’s op­er­a­tional risk re­duc­tion.

Your code is a strat­egy memo to strangers who will main­tain it at 2am dur­ing an out­age. Optimize for their com­pre­hen­sion, not your el­e­gance. The se­nior en­gi­neers I re­spect most have learned to trade clev­er­ness for clar­ity, every time.

Treat your tech­nol­ogy choices like an or­ga­ni­za­tion with a small innovation to­ken” bud­get. Spend one each time you adopt some­thing ma­te­ri­ally non-stan­dard. You can’t af­ford many.

The punch­line is­n’t never in­no­vate.” It’s innovate only where you’re uniquely paid to in­no­vate.” Everything else should de­fault to bor­ing, be­cause bor­ing has known fail­ure modes.

The best tool for the job” is of­ten the least-worst tool across many jobs”-be­cause op­er­at­ing a zoo be­comes the real tax.

Early in my ca­reer, I be­lieved great work would speak for it­self. I was wrong. Code sits silently in a repos­i­tory. Your man­ager men­tions you in a meet­ing, or they don’t. A peer rec­om­mends you for a pro­ject, or some­one else.

In large or­ga­ni­za­tions, de­ci­sions get made in meet­ings you’re not in­vited to, us­ing sum­maries you did­n’t write, by peo­ple who have five min­utes and twelve pri­or­i­ties. If no one can ar­tic­u­late your im­pact when you’re not in the room, your im­pact is ef­fec­tively op­tional.

This is­n’t strictly about self-pro­mo­tion. It’s about mak­ing the value chain leg­i­ble to every­one- in­clud­ing your­self.

We cel­e­brate cre­ation in en­gi­neer­ing cul­ture. Nobody gets pro­moted for delet­ing code, even though dele­tion of­ten im­proves a sys­tem more than ad­di­tion. Every line of code you don’t write is a line you never have to de­bug, main­tain, or ex­plain.

Before you build, ex­haust the ques­tion: What would hap­pen if we just… did­n’t?” Sometimes the an­swer is nothing bad,” and that’s your so­lu­tion.

The prob­lem is­n’t that en­gi­neers can’t write code or use AI to do so. It’s that we’re so good at writ­ing it that we for­get to ask whether we should.

With enough users, every ob­serv­able be­hav­ior be­comes a de­pen­dency - re­gard­less of what you promised. Someone is scrap­ing your API, au­tomat­ing your quirks, caching your bugs.

This cre­ates a ca­reer-level in­sight: you can’t treat com­pat­i­bil­ity work as maintenance” and new fea­tures as real work.” Compatibility is prod­uct.

Design your dep­re­ca­tions as mi­gra­tions with time, tool­ing, and em­pa­thy. Most API de­sign” is ac­tu­ally API re­tire­ment.”

When a pro­ject drags, the in­stinct is to blame ex­e­cu­tion: peo­ple aren’t work­ing hard enough, the tech­nol­ogy is wrong, there aren’t enough en­gi­neers. Usually none of that is the real prob­lem.

In large com­pa­nies, teams are your unit of con­cur­rency, but co­or­di­na­tion costs grow geo­met­ri­cally as teams mul­ti­ply. Most slow­ness is ac­tu­ally align­ment fail­ure - peo­ple build­ing the wrong things, or the right things in in­com­pat­i­ble ways.

Senior en­gi­neers spend more time clar­i­fy­ing di­rec­tion, in­ter­faces, and pri­or­i­ties than writing code faster” be­cause that’s where the ac­tual bot­tle­neck lives.

In a large com­pany, count­less vari­ables are out­side your con­trol - or­ga­ni­za­tional changes, man­age­ment de­ci­sions, mar­ket shifts, prod­uct piv­ots. Dwelling on these cre­ates anx­i­ety with­out agency.

The en­gi­neers who stay sane and ef­fec­tive zero in on their sphere of in­flu­ence. You can’t con­trol whether a re­org hap­pens. You can con­trol the qual­ity of your work, how you re­spond, and what you learn. When faced with un­cer­tainty, break prob­lems into pieces and iden­tify the spe­cific ac­tions avail­able to you.

This is­n’t pas­sive ac­cep­tance but it is strate­gic fo­cus. Energy spent on what you can’t change is en­ergy stolen from what you can.

Every ab­strac­tion is a bet that you won’t need to un­der­stand what’s un­der­neath. Sometimes you win that bet. But some­thing al­ways leaks, and when it does, you need to know what you’re stand­ing on.

Senior en­gi­neers keep learn­ing lower level” things even as stacks get higher. Not out of nos­tal­gia, but out of re­spect for the mo­ment when the ab­strac­tion fails and you’re alone with the sys­tem at 3am. Use your stack.

But keep a work­ing model of its un­der­ly­ing fail­ure modes.

Writing forces clar­ity. When I ex­plain a con­cept to oth­ers - in a doc, a talk, a code re­view com­ment, even just chat­ting with AI - I dis­cover the gaps in my own un­der­stand­ing. The act of mak­ing some­thing leg­i­ble to some­one else makes it more leg­i­ble to me.

This does­n’t mean that you’re go­ing to learn how to be a sur­geon by teach­ing it, but the premise still holds largely true in the soft­ware en­gi­neer­ing do­main.

This is­n’t just about be­ing gen­er­ous with knowl­edge. It’s a self­ish learn­ing hack. If you think you un­der­stand some­thing, try to ex­plain it sim­ply. The places where you stum­ble are the places where your un­der­stand­ing is shal­low.

Teaching is de­bug­ging your own men­tal mod­els.

Glue work - doc­u­men­ta­tion, on­board­ing, cross-team co­or­di­na­tion, process im­prove­ment - is vi­tal. But if you do it un­con­sciously, it can stall your tech­ni­cal tra­jec­tory and burn you out. The trap is do­ing it as helpfulness” rather than treat­ing it as de­lib­er­ate, bounded, vis­i­ble im­pact.

Timebox it. Rotate it. Turn it into ar­ti­facts: docs, tem­plates, au­toma­tion. And make it leg­i­ble as im­pact, not as per­son­al­ity trait.

Priceless and in­vis­i­ble is a dan­ger­ous com­bi­na­tion for your ca­reer.

I’ve learned to be sus­pi­cious of my own cer­tainty. When I win” too eas­ily, some­thing is usu­ally wrong. People stop fight­ing you not be­cause you’ve con­vinced them, but be­cause they’ve given up try­ing - and they’ll ex­press that dis­agree­ment in ex­e­cu­tion, not meet­ings.

Real align­ment takes longer. You have to ac­tu­ally un­der­stand other per­spec­tives, in­cor­po­rate feed­back, and some­times change your mind pub­licly.

The short-term feel­ing of be­ing right is worth much less than the long-term re­al­ity of build­ing things with will­ing col­lab­o­ra­tors.

Every met­ric you ex­pose to man­age­ment will even­tu­ally be gamed. Not through mal­ice, but be­cause hu­mans op­ti­mize for what’s mea­sured.

If you track lines of code, you’ll get more lines. If you track ve­loc­ity, you’ll get in­flated es­ti­mates.

The se­nior move: re­spond to every met­ric re­quest with a pair. One for speed. One for qual­ity or risk. Then in­sist on in­ter­pret­ing trends, not wor­ship­ing thresh­olds. The goal is in­sight, not sur­veil­lance.

Senior en­gi­neers who say I don’t know” aren’t show­ing weak­ness - they’re cre­at­ing per­mis­sion. When a leader ad­mits un­cer­tainty, it sig­nals that the room is safe for oth­ers to do the same. The al­ter­na­tive is a cul­ture where every­one pre­tends to un­der­stand and prob­lems stay hid­den un­til they ex­plode.

I’ve seen teams where the most se­nior per­son never ad­mit­ted con­fu­sion, and I’ve seen the dam­age. Questions don’t get asked. Assumptions don’t get chal­lenged. Junior en­gi­neers stay silent be­cause they as­sume every­one else gets it.

Model cu­rios­ity, and you get a team that ac­tu­ally learns.

Early in my ca­reer, I fo­cused on the work and ne­glected net­work­ing. In hind­sight, this was a mis­take. Colleagues who in­vested in re­la­tion­ships - in­side and out­side the com­pany - reaped ben­e­fits for decades.

They heard about op­por­tu­ni­ties first, could build bridges faster, got rec­om­mended for roles, and co-founded ven­tures with peo­ple they’d built trust with over years.

Your job is­n’t for­ever, but your net­work is. Approach it with cu­rios­ity and gen­eros­ity, not trans­ac­tional hus­tle.

When the time comes to move on, it’s of­ten re­la­tion­ships that open the door.

When sys­tems get slow, the in­stinct is to add: caching lay­ers, par­al­lel pro­cess­ing, smarter al­go­rithms. Sometimes that’s right. But I’ve seen more per­for­mance wins from ask­ing what are we com­put­ing that we don’t need?”

Deleting un­nec­es­sary work is al­most al­ways more im­pact­ful than do­ing nec­es­sary work faster. The fastest code is code that never runs.

Before you op­ti­mize, ques­tion whether the work should ex­ist at all.

The best process makes co­or­di­na­tion eas­ier and fail­ures cheaper. The worst process is bu­reau­cratic the­ater - it ex­ists not to help but to as­sign blame when things go wrong.

If you can’t ex­plain how a process re­duces risk or in­creases clar­ity, it’s prob­a­bly just over­head.

And if peo­ple are spend­ing more time doc­u­ment­ing their work than do­ing it, some­thing has gone deeply wrong.

Early in your ca­reer, you trade time for money - and that’s fine. But at some point, the cal­cu­lus in­verts. You start to re­al­ize that time is the non-re­new­able re­source.

I’ve watched se­nior en­gi­neers burn out chas­ing the next promo level, op­ti­miz­ing for a few more per­cent­age points of com­pen­sa­tion. Some of them got it. Most of them won­dered, af­ter­ward, if it was worth what they gave up.

The an­swer is­n’t don’t work hard.” It’s know what you’re trad­ing, and make the trade de­lib­er­ately.”

Expertise comes from de­lib­er­ate prac­tice - push­ing slightly be­yond your cur­rent skill, re­flect­ing, re­peat­ing. For years. There’s no con­densed ver­sion.

But here’s the hope­ful part: learn­ing com­pounds when it cre­ates new op­tions, not just new trivia. Write - not for en­gage­ment, but for clar­ity. Build reusable prim­i­tives. Collect scar tis­sue into play­books.

The en­gi­neer who treats their ca­reer as com­pound in­ter­est, not lot­tery tick­ets, tends to end up much fur­ther ahead.

Twenty-one lessons sounds like a lot, but they re­ally come down to a few core ideas: stay cu­ri­ous, stay hum­ble, and re­mem­ber that the work is al­ways about peo­ple - the users you’re build­ing for and the team­mates you’re build­ing with.

A ca­reer in en­gi­neer­ing is long enough to make plenty of mis­takes and still come out ahead. The en­gi­neers I ad­mire most aren’t the ones who got every­thing right - they’re the ones who learned from what went wrong, shared what they dis­cov­ered, and kept show­ing up.

If you’re early in your jour­ney, know that it gets richer with time. If you’re deep into it, I hope some of these res­onate.

...

Read the original on addyosmani.com »

2 414 shares, 40 trendiness

The Unbearable Joy of Sitting Alone in A Café

It’s con­tra­dic­tory to sit alone in a café. It’s against the rea­son cafés ex­ist.

They are de­signed as meet­ing spaces. There is no table with a sin­gle chair. Even the ones placed right by the win­dow with high seat­ing are big ta­bles with many chairs.

Cafés are com­mu­nity spaces. Most go there to see their loved ones, friends, or col­leagues.

You find only a few peo­ple sit­ting alone. Most are buried in their lap­tops, work­ing hard to make a liv­ing in their own worlds, what­ever world they have.

When I took time off from work, I chose a stay­ca­tion. Unlike most of my friends, who vis­ited Japan in 2025.

When I heard their ex­pe­ri­ences, I was jeal­ous. When I told them my stay­ca­tion plans of do­ing noth­ing for four weeks, they were jeal­ous.

While off work, I wanted to slow time down as much as I could. The best way to freeze time, I read some­where, is to get a dog. Luckily, I have one al­ready. So, I took long walks with my dog.

What used to feel like 10 min­utes be­tween break­fast and lunch while work­ing be­came a full-blown day. Even though I was spend­ing two hours walk­ing my dog in­stead of a 30-40 minute rush, it felt like an eter­nity. A peace­ful eter­nity.

On the sec­ond day, I de­cided to leave my phone at home, so I lived those two hours to the fullest. I did­n’t take any de­vice that could con­nect me to the in­ter­net or to other peo­ple.

But all the anx­i­ety evap­o­rated af­ter 30 min­utes.

It was­n’t that no­body could reach out to me that felt like an es­cape; it was that I could­n’t reach out to any­one or any­thing that caused the tur­moil.

I had no pos­si­bil­ity to text any­one. No pos­si­bil­ity to watch or read. No chance to look up any­thing to ful­fill my cu­rios­ity.

My mind was alone af­ter a long time.

There were a few mo­ments I put my hand into my pocket to take out my phone to look up some­thing I was cu­ri­ous about. My phone was­n’t there.

On the sec­ond day, I ran­domly walked into a neigh­bor­hood café. I or­dered an amer­i­cano with a dou­ble shot of espresso.

Sipping a hot amer­i­cano feels dif­fer­ent when you are in a rush to catch a sub­way. Its pur­pose is to wake you up. A sip from that lit­tle hole in a sin­gle-use cap burns my tongue every time. I de­spise that.

With a porce­lain cup, you don’t have that. Coffee changes its pur­pose. It be­comes a plea­sure.

I sat down with a proper cup of amer­i­cano. My dog crawled un­der the table.

I was sit­ting alone in a café with a dog that had crawled un­der the table with­out any elec­tron­ics that could dis­tract me.

Distract me from, ba­si­cally, noth­ing.

It was pure de­light. Every el­e­ment. Or rather, the non-ex­is­tence of any el­e­ment. No phone. No head­phones. No tablet. No lap­top.

My mind was just drift­ing with the chat­ter in the café. I left my­self to the flow.

When you let your thoughts wan­der, they take you on a jour­ney you’ll never think pos­si­ble. You re­flect on the small­est de­tails of your fast life. Your brain ab­sorbs all the mis­takes you’ve made. You ac­cept that you can’t change fail­ures any­more, as much as you feel guilty.

You might as well not worry about them and fo­cus on what you can change: what you do now. And what you will do next.

The next day, I left my phone at home again and de­cided to stop by the same café. I was lucky; I sat down at the same table.

Sitting alone in a café with­out dis­trac­tions re­veals a lot about peo­ple. The same peo­ple you pass by in a split sec­ond while rush­ing from home to work, from a meet­ing to a meet­ing. The in­vis­i­ble sud­denly ap­pears right in front of you. People don’t go away in two sec­onds. They stay. They sip a cof­fee. They talk with oth­ers, laugh, cry, and worry. Oh, worry.

Worry is only vis­i­ble in peo­ple’s eyes. Eyes are the chan­nel of the heart. You have to close your ears and look at peo­ple’s eyes to see their hearts.

You re­al­ize that look­ing into eyes is fright­en­ing—both for you and the other per­son. You try to avoid it, but even­tu­ally make eye con­tact be­cause no­body is phys­i­cally mov­ing any­where.

As none of you are pass­ing by in a sec­ond, you mimic look­ing at some­thing else. They con­tinue their con­ver­sa­tion. But you saw their worry, and you can’t help but try to un­der­stand.

You leave the café to avoid mak­ing things awk­ward.

I went there the next day. This time, my table was oc­cu­pied. I don’t know when it be­came my table. But it felt like that. I found an­other one. It was closer to the staff.

Sitting alone in a café with­out dis­trac­tions shows you how a café works. You never con­tem­plate how they op­er­ate be­hind that gi­ant cof­fee ma­chine while you’re wait­ing for your cof­fee be­fore you run to catch the next bus, tram, sub­way, or taxi. You never ru­mi­nate when you sip from a sin­gle-use cup and burn your tongue.

You no­tice how the staff cir­cu­lates porce­lain cups, from dirty to clean, to the top of the cof­fee ma­chine. You ob­serve the staff’s re­ac­tions to each cus­tomer. You try to an­a­lyze if some­one is a reg­u­lar by notic­ing how the staff talks.

You won­der whether they con­sider you a reg­u­lar, since you’ve been there for the last cou­ple of days. Or they call you a creepy guy with a dog. You will never know. You’re not fine with never know­ing.

You promise your­self to come the next day to ob­serve how the staff talks to you.

I again went to the same café. Unlucky me. A dif­fer­ent staff were work­ing on that day. Yet I or­dered the same: a cup of amer­i­cano with a dou­ble shot of espresso.

Sitting alone in a café with­out dis­trac­tions, with a dog that had crawled un­der the table, brings a light to a truth: you can’t con­trol or in­flu­ence other peo­ple’s thoughts and feel­ings, no mat­ter what you do. Staff may think of you as a weirdo with a dog; your friends might want to be in your place; your fam­ily might be ner­vous be­cause they can’t reach out to you.

You know you can’t change any of those un­less you change who you are. It makes you feel alone and pow­er­less.

You are alone and pow­er­less. You en­counter a deep chal­lenge.

The next day, I did­n’t go to the café. I in­stead took an even longer walk. I went there the fol­low­ing day, know­ing I had faced that chal­lenge in my longest walk.

Sitting alone in a café with­out dis­trac­tions shows every­one you’re alone.

Many avoid at all costs. That’s why every­body looks at you with won­der­ing eyes. They are afraid of your pow­er­ful joy. They can’t grasp why some­one would do this to them­selves. They are hes­i­tant but are think­ing of do­ing the same.

Then you re­al­ize you’re plant­ing thoughts in peo­ple’s minds that you can’t con­trol. Feelings are feel­ings. Thoughts are thoughts.

Just at the mo­ment you think you are alone again, you see an­other weirdo across the café sit­ting alone with­out dis­trac­tions. That weirdo is look­ing at your sleep­ing-in-a-crois­sant-shape dog un­der the table. Weirdo is en­joy­ing the mo­ment, while your dog is on an ad­ven­ture in her sec­ond dream.

You smile. You know you’re not alone. You are one weirdo sit­ting at a dis­tance from one other. You know there are many.

Maybe one of them is read­ing this and feel­ing heard. Perhaps one will never see this and will al­ways feel alone. But it only needs one look around. You glance over the café and leave with a smile.

The next day, I went there again. This time, I put in an in­ten­tional dis­trac­tion. A good one.

Sitting alone in a café with­out dis­trac­tions only gets bet­ter when there is some­thing to write on. Not with a key­board. You must use your sin­gle hand to write, not two. Ideally, with a pen on pa­per.

The pen is meant to slow you down. The words should­n’t land on pa­per at the speed of think­ing or even talk­ing.

The writ­ing must hurt your wrist or hand. It must turn into a bur­den. That pain is a sig­nal telling you that you have writ­ten long enough. Maybe you wrote only five lines. Perhaps one thou­sand.

...

Read the original on candost.blog »

3 301 shares, 27 trendiness

Street Fighter II, The World Warrier

This ar­ti­cle is part of a se­ries about Street Fighter II and the CPS-1. It is rec­om­mended to read the pre­vi­ous en­tries be­fore read­ing this one.

One of my fa­vorite anec­dote about Street Fighter II is Akiman’s ac­count of an is­sue dis­cov­ered shortly be­fore ship­ping.

Just three days be­fore the dead­line, I dis­cov­ered some­thing hor­ri­ble. I had made a mis­take with the sub­ti­tle World Warrior”, mis-spelling it World Warrier.”

To fully un­der­stand the is­sue, we need to dig into how the ar­cade hard­ware works. The CPS-1 is a su­per tile draw­ing ma­chine. It can draw a lot of tiles but can­not al­ter them. They are taken from the GFX ROM as they are and sent to the screen (although they can be flipped hor­i­zon­tally or ver­ti­cally).

The GFX ROM and the 68000 in­struc­tions ROM as burned sep­a­rately. The prob­lem Akiman de­scribe is that the GFX ROM had been burned but he could still make changes to the in­struc­tions.

But how could he fix the mis­take if the art­work was set in stone at this point?

Now I can safely tell this story too, but we ac­tu­ally did­n’t dis­cover it un­til sev­eral months af­ter all the sprite work had been done. Since the logo had al­ready been cre­ated, I could­n’t just go in and change the let­ter at this point.

Maybe I can just force it to look like an o’,” I thought. I tried lay­er­ing var­i­ous other sprites over it un­til fi­nally, it looked like an o’. Phew!

Akiman de­scrip­tion of the so­lu­tion left me want­ing more de­tails. How did he turn an e’ into an o’? Since I had a sheet ex­trac­tor, I looked for the text and sure enough, the logo and the typo were found on sheet 0x7B00.

The logo is drawn via 16 draw calls us­ing tiles 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, and 0xDF.

The way Akiman solved his prob­lem show that you have to be prac­ti­cal in or­der to ship. He no­ticed that there was an or’ in World’ which would kinda fit in place of the ier’. So, he dropped the three last tiles 0xDD, 0xDE, and 0xDF and re­placed them with 0xCD and 0xCE.

That was bet­ter but it only dis­placed the prob­lem since the bor­rowed right leg of the W’ looked like an l’ in­stead of an i’. The logo now read The World Warrlor’.

At this point, what was needed was a way to slice the top of the l’ to make it look like a dot on top of an i’ but how could he do that since the 68000 can­not write in a tile?

The last part of the puz­zle comes from Guile’s calves. If you look closely at tile 0x96 you will no­tice that it has only one pixel vis­i­ble in the lower left cor­ner.

Something that I omit­ted to men­tion ear­lier is that the palette man­age­ment is en­tirely un­der the 68000 con­trol. The CPU is free to is­sue a tile draw­ing com­mand us­ing what­ever palette it pleases.

Guile’s green palette is not use­ful since the logo uses blue col­ors. But if we place them side by side, we no­tice that in­dex 14 is dark green in Guile’s palette but dark blue in the logo palette.

Using tile 0x96 with the logo palette al­lows the 68000 to have a (very ex­pen­sive) sys­tem where 255 pix­els are wasted to trans­parency but the 256th can be used like a pen­cil.

That pen­cil-tile is used to is­sue three draw com­mand with co­or­di­nates over­lap­ping the l’. This ef­fec­tively cre­ates a line which cuts the top part and make it look like the dot at the top of an i’.

If you ever won­dered why the i’ of Warrior’ looked weird all these years, now you know.

The typo was fixed in later ver­sions of Street Fighter 2 where the World Warrior” set of tiles fea­tures a proper IOR.

Ironically these are not used since the sub-ti­tle was changed from World Warrior” to Champion Edition” and then Hyper-fighting”.

...

Read the original on fabiensanglard.net »

4 278 shares, 15 trendiness

Can I finally start using Wayland in 2026?

Can I fi­nally start us­ing Wayland in 2026?

Wayland is the suc­ces­sor to the X server (X11, Xorg) to im­ple­ment the graph­ics stack on Linux. The Wayland

pro­ject was ac­tu­ally started in 2008, a year be­fore I cre­ated the i3 tiling

win­dow man­ager for X11 in 2009 — but for the last 18 years (!), Wayland was never us­able on my com­put­ers. I don’t want to be stuck on dep­re­cated soft­ware, so I try to start us­ing Wayland each year, and this ar­ti­cles out­lines what keeps me from mi­grat­ing to Wayland in 2026.

For the first few years, Wayland rarely even started on my ma­chines. When I was lucky enough for some­thing to show up, I could start some toy demo apps in the demo com­pos­i­tor Weston.

Around 2014, GNOME started sup­port­ing Wayland. KDE fol­lowed a few years later. Major ap­pli­ca­tions (like Firefox, Chrome or Emacs) have been slower to adopt Wayland and needed users to opt into ex­per­i­men­tal im­ple­men­ta­tions via cus­tom flags or en­vi­ron­ment vari­ables, un­til very re­cently, or — in some cases, like

gee­qie — still as of to­day.

Unfortunately, the dri­ver sup­port sit­u­a­tion re­mained poor for many years. With nVidia graph­ics cards, which are the only cards that sup­port my 8K

mon­i­tor, Wayland would ei­ther not work at all or ex­hibit heavy graph­ics glitches and crashes.

In the 2020s, more and more dis­tri­b­u­tions an­nounced look­ing to switch to Wayland by de­fault or even drop their X11

ses­sions, and RHEL is wind­ing down their con­tri­bu­tions to the X

server.

Modern Linux dis­tri­b­u­tions like Asahi Linux (for Macs, with their own GPU dri­ver!) clearly con­sider Wayland their pri­mary desk­top stack, and only sup­port X11 on a best-ef­fort ba­sis.

So the pres­sure to switch to Wayland is mount­ing! Is it ready now? What’s miss­ing?

I’m test­ing with my lab PC, which is a slightly up­graded ver­sion of my 2022

high-end Linux PC.

I de­scribe my setup in more de­tails in stapel­berg uses this: my 2020 desk

setup.

Most im­por­tantly for this ar­ti­cle, I use a Dell 8K 32″

mon­i­tor (resolution: 7680x4320!), which, in my ex­pe­ri­ence, is only com­pat­i­ble with nVidia graph­ics cards (I try other cards some­times).

Hence, both the lab PC and my main PC con­tain an nVidia GPU:

For many years, nVidia dri­vers were en­tirely un­sup­ported un­der Wayland.

Apparently, nVidia re­fused to sup­port the API that Wayland was us­ing, in­sist­ing that their EGLStreams ap­proach was su­pe­rior. Luckily, with nVidia dri­ver 495 (late 2021), they added sup­port for GBM (Generic Buffer Manager).

But, even with GBM sup­port, while you could now start many Wayland ses­sions, the ses­sion would­n’t run smoothly: You would see se­vere graph­ics glitches and ar­ti­facts, pre­vent­ing you from get­ting any work done.

The so­lu­tion for the glitches was ex­plicit sync sup­port: be­cause the nVidia dri­ver does not sup­port im­plicit sync (like AMD or Intel), Wayland (and wl­roots, and sway) needed to get ex­plicit sync

sup­port.

Sway 1.11 (June 2025) and wl­roots 0.19.0 are the first ver­sion with ex­plicit sync sup­port.

With the nVidia dri­ver now work­ing per se with Wayland, un­for­tu­nately that’s still not good enough to use Wayland in my setup: my Dell UP3218K

mon­i­tor re­quires two DisplayPort 1.4 con­nec­tions with MST (Multi Stream Transport) and TILE sup­port. This com­bi­na­tion worked just fine un­der X11 for the last 8+ years.

While GNOME suc­cess­fully con­fig­ures the mon­i­tor with its na­tive res­o­lu­tion of 7680x4320@60, the mon­i­tor in­cor­rectly shows up as two sep­a­rate mon­i­tors in sway.

The rea­son be­hind this be­hav­ior is that wl­roots does not sup­port the TILE

prop­erty (issue #1580 from

2019). Luckily, in 2023, con­trib­u­tor EBADBEEF sent draft merge re­quest

!4154, which adds sup­port for the TILE prop­erty.

But, even with the TILE patch, my mon­i­tor would not work cor­rectly: The right half of the mon­i­tor would just stay black. The full pic­ture is vis­i­ble when tak­ing a screen­shot with grim, so it seems like an out­put is­sue. I had a few ex­changes about this with EBADBEEF start­ing in August 2025 (thanks for tak­ing a look!), but we could­n’t fig­ure out the is­sue.

A quar­ter later, I had made good ex­pe­ri­ences re­gard­ing de­bug­ging com­plex is­sues with the cod­ing as­sis­tant Claude Code

(Opus 4.5 at the time of writ­ing), so I de­cided to give it an­other try. Over two days, I ran a num­ber of tests to nar­row down the is­sue, let­ting Claude an­a­lyze source code (of sway, wl­roots, Xorg, mesa, …) and pro­duce test pro­grams that I could run man­u­ally.

Ultimately, I ended up with a min­i­mal re­pro­ducer pro­gram (independent of Wayland) that shows how the SRC_X DRM prop­erty does not work on nVidia (but does work on Intel, for ex­am­ple!): I posted a bug re­port with a video in the

nVidia

fo­rum

and hope an nVidia en­gi­neer will take a look!

Crucially, with the bug now iden­ti­fied, I had Claude im­ple­ment a workaround: copy the right half of the screen (at SRC_X=3840) to an­other buffer, and then dis­play that buffer, but with SRC_X=0.

With that

patch

ap­plied, for the first time, I can use Sway on my 8K mon­i­tor! 🥳

By the way, when I men­tioned that GNOME suc­cess­fully con­fig­ures the na­tive res­o­lu­tion, that does­n’t mean the mon­i­tor is us­able with GNOME! While GNOME sup­ports tiled dis­plays, the up­dates of in­di­vid­ual tiles are not syn­chro­nized, so you see heavy tear­ing in the mid­dle of the screen, much worse than any­thing I have ever ob­served un­der X11. GNOME/mutter merge re­quest

!4822 should hope­fully ad­dress this.

During 2025, I switched all my com­put­ers to NixOS. Its de­clar­a­tive ap­proach is re­ally nice for do­ing such tests, be­cause you can re­li­ably re­store your sys­tem to an ear­lier ver­sion.

To make a Wayland/sway ses­sion avail­able on my NixOS 25.11 in­stal­la­tion, I added the fol­low­ing lines to my NixOS con­fig­u­ra­tion file (configuration.nix):

I also added the fol­low­ing Wayland-specific pro­grams to en­vi­ron­ment.sys­tem­Pack­ages:

Note that ac­ti­vat­ing this con­fig­u­ra­tion kills your run­ning X11 ses­sion, if any.

Just to be sure, I re­booted the en­tire ma­chine af­ter chang­ing the con­fig­u­ra­tion.

With this setup, I spent about one full work day in a Wayland ses­sion. Trying to ac­tu­ally get some work done un­cov­ers is­sues that might not show in ca­sual test­ing. Most of the day was spent try­ing to fix Wayland is­sues 😅. The fol­low­ing sec­tions ex­plain what I have learned/​ob­served.

Many years ago, when Wayland be­came more pop­u­lar, peo­ple asked on the i3 is­sue tracker if i3 would be ported to Wayland. I said no: How could I port a pro­gram to an en­vi­ron­ment that does­n’t even run on any of my com­put­ers? But also, I knew that with work­ing a full-time job, I would­n’t have time to be an early adopter and shape Wayland de­vel­op­ment.

This at­ti­tude re­sulted in Drew DeVault start­ing the

Sway pro­ject around 2016, which aims to be a Wayland ver­sion of i3. I don’t see Sway as com­pe­ti­tion. Rather, I thought it was amaz­ing that peo­ple liked the i3 pro­ject so much that they would go through the trou­ble of cre­at­ing a sim­i­lar pro­gram for other en­vi­ron­ments! What a nice com­pli­ment! 😊

Sway aims to be com­pat­i­ble with i3 con­fig­u­ra­tion files, and it mostly is.

If you’re cu­ri­ous, here is what I changed from the Sway de­faults, mostly mov­ing key bind­ings around for the NEO key­board lay­out I use, and con­fig­ur­ing in­put/​out­put blocks that I for­merly con­fig­ured in my

~/.xsession

file:

I en­coun­tered the fol­low­ing is­sues with Sway:

I don’t know how I can con­fig­ure the same li­b­in­put set­tings that I had be­fore. See xin­put-list-props-mx-ergo.txt

for what I have on X11. Sway’s avail­able ac­cel_pro­file set­tings do not seem to match what I used be­fore.

The mouse cur­sor / pointer seems laggy, some­how?! It seems to take longer to re­act when I move the track­ball, and it also seems to move less smoothly across the screen.

Simon Ser sus­pects that this might be be­cause hard­ware cur­sor sup­port might not work with the nVidia dri­vers cur­rently.

No Xwayland scal­ing: pro­grams started via Xwayland are blurry (by de­fault) or dou­ble-scaled (when set­ting Xft.dpi: 288). This is a Sway-specific lim­i­ta­tion: KDE fixed this in

2022. From

Sway is­sue #2966, I can tell that Sway de­vel­op­ers do not seem to like this ap­proach for some rea­son, but that’s very un­for­tu­nate for my mi­gra­tion: The back­wards com­pat­i­bil­ity op­tion of run­ning older pro­grams through Xwayland is ef­fec­tively un­avail­able to me.

Sometimes, key­board short­cuts seem to be ex­e­cuted twice! Like, when I fo­cused the first of five Chrome win­dows in a stack and moved that win­dow to an­other work­space, two win­dows would be moved in­stead of one. I also see mes­sages like this one (not ex­actly cor­re­lated with the dou­ble-short­cut prob­lem, though):

[ERROR] [wlr] [libinput] event0 - https: kinT (kint36): client bug: event

pro­cess­ing lag­ging be­hind by 32ms, your sys­tem is too slow

…and that seems wrong to me. My high-end Linux

PC cer­tainly is­n’t slow by any mea­sure.

When I first started GTK pro­grams like GIMP or Emacs, I no­ticed all fonts were way too large! Apparently, I still had some scal­ing-re­lated set­tings that I needed to re­set like so:

gset­tings re­set org.gnome.desk­top.in­ter­face scal­ing-fac­tor

gset­tings re­set org.gnome.desk­top.in­ter­face text-scal­ing-fac­tor

Some pro­grams like gee­qie ap­par­ently need an ex­plicit ex­port GDK_BACKEND=wayland en­vi­ron­ment vari­able, oth­er­wise they run in Xwayland. Weird.

I also no­ticed that font ren­der­ing is dif­fer­ent be­tween X11 and Wayland! The dif­fer­ence is vis­i­ble in Chrome browser tab ti­tles and the URL bar, for ex­am­ple:

At first I thought that maybe Wayland de­faults to dif­fer­ent font-an­tialias­ing and font-hint­ing set­tings, but I tried ex­per­i­ment­ing with the fol­low­ing set­tings (which de­fault to font-an­tialias­ing=grayscale and font-hint­ing=slight), but could­n’t get things to ren­der like they did be­fore:

gset­tings set org.gnome.desk­top.in­ter­face font-an­tialias­ing rgba’

gset­tings set org.gnome.desk­top.in­ter­face font-hint­ing full’

Update: Thanks to

Hugo for point­ing out that un­der Wayland, GTK3 ig­nores the ~/.config/gtk-3.0/settings.ini

con­fig­u­ra­tion file and uses dconf ex­clu­sively! Setting the fol­low­ing dconf set­ting makes the font ren­der­ing match:

gset­tings set org.gnome.desk­top.in­ter­face font-name Cantarell 11’

I quickly ran into a dif­fer­ence in ar­chi­tec­ture be­tween the two pro­grams:

i3lock shows a screen locker win­dow. When you kill i3lock, the screen is un­locked.

When you kill sway­lock, you end up in a Red Screen Of Death.

To get out of this state, you need to restart sway­lock and un­lock. You can un­lock from the com­mand line by send­ing SIGUSR1 to the sway­lock process.

This was very sur­pris­ing to me, but is by (Wayland) de­sign! See Sway is­sue

#7046 for de­tails, and this quote from the ext-ses­sion-lock-v1 Wayland pro­to­col:

The com­pos­i­tor must stop ren­der­ing and pro­vide in­put to nor­mal clients. Instead the com­pos­i­tor must blank all out­puts with an opaque color such that their nor­mal con­tent is fully hid­den.”

OK, so when you start sway­lock via SSH for test­ing, re­mem­ber to al­ways un­lock in­stead of just can­celling sway­lock with Ctrl+C. And hope it never crashes.

I used to start i3lock via a wrap­per script, which turns off the mon­i­tor (input wakes it up):

With Wayland, the DPMS be­hav­ior has to be im­ple­mented dif­fer­ently, with swayi­dle:

The i3 win­dow man­ager can be ex­tended via its IPC in­ter­face (interprocess

com­mu­ni­ca­tion).

I use a few small tools that use this in­ter­face.

I no­ticed the fol­low­ing is­sues when us­ing these tools with Sway:

On X11, I use the rxvt-uni­code

...

Read the original on michael.stapelberg.ch »

5 266 shares, 23 trendiness

Web development is fun again

I re­mem­ber when PHP 4 was a thing. jQuery was new and shiny. Sites were built with ta­bles, not divs. Dreamweaver felt like a life hack. Designs were sliced in Photoshop. Databases lived in ph­p­MyAd­min.

It prob­a­bly did­n’t feel like it at the time, but look­ing back, those were sim­pler days. The en­tire con­cept of the de­vel­op­ment cy­cle could fit in my head. There was com­plex­ity in build­ing web ap­pli­ca­tions, but it was all man­age­able. If you had an idea, you could prob­a­bly build it.

As a solo de­vel­oper, you could man­age every­thing. From idea to ex­e­cu­tion. Or at least, it felt that way.

I’m prob­a­bly ro­man­ti­ciz­ing the past, but you get the idea.

Today, it’s hard to do web de­vel­op­ment right.

On the fron­tend, you have build pipelines, bundlers, CSS frame­works with their own tool­chains, pro­gres­sive web apps, Core Web Vitals, SEO, lay­out shifts, src­set/​re­spon­sive im­ages… I re­mem­ber when the biggest chal­lenge was IE6 com­pat­i­bil­ity.

On the back­end, there are de­sign pat­terns, unit tests, code cov­er­age, APIs, per­for­mance con­cerns, de­pen­dency man­age­ment, in­fra­struc­ture, mon­i­tor­ing, log trac­ing, ob­serv­abil­ity…

Each area of ex­per­tise has grown up - prob­a­bly for the bet­ter - but it also de­mands deeper do­main knowl­edge. I chose to spe­cial­ize in back­end and server in­fra­struc­ture. I had to step back from fron­tend work be­cause I could­n’t keep up with its tool­ing while de­vel­op­ing my back­end skills.

As a solo de­vel­oper, it’s now a lot harder to man­age every­thing.

They’re far from per­fect, but claude and codex gave me the lever­age I des­per­ately needed. They’ve brought me back to lev­els of pro­duc­tiv­ity I haven’t felt in years. I feel like I can man­age the en­tire stack again - with con­fi­dence.

I can go from idea to ex­e­cu­tion in days.

Suddenly, the com­plex­ity of each do­main mat­ters a lot less.

Oh no, you’re vibe cod­ing - bet it’s all slop and code noise!

Over the past two decades, I’ve worked with a lot of tal­ented peo­ple: back­end de­vel­op­ers, fron­tend de­vel­op­ers, mar­keters, lead­ers, and more. I can lean on those ex­pe­ri­ences, fall back on how they did things, and im­ple­ment their meth­ods with AI.

I can re­li­ably re­pro­duce their cod­ing stan­dards, tone of voice, tac­tics, and processes. Starting a new pro­ject once felt in­sur­mount­able. Now, it feels re­al­is­tic again.

When AI gen­er­ates code, I know when it’s good and when it’s not. I’ve seen the good and the bad, and I can it­er­ate from there. Even with re­fine­ment and back-and-forth prompt­ing, I’m eas­ily 10x more pro­duc­tive with AI than with­out it.

The goal has­n’t changed: build qual­ity soft­ware that meets mod­ern stan­dards. The goal­post is still far out. But now I have a rocket-pow­ered soc­cer ball - and I can fi­nally reach it again.

There’s men­tal space for cre­ativ­ity in build­ing soft­ware again.

My head is­n’t con­stantly full of build pipelines, testa­bil­ity con­cerns, code pat­terns, un­fixed bugs… I’m con­fi­dent I can cover that with help from AI. It still needs to be done, but it’s done so much faster - and it no longer feels over­whelm­ing.

That leaves room to ex­per­i­ment with UI and UX, to try ideas and throw them away. To add small qual­ity-of-life im­prove­ments I could­n’t jus­tify be­fore, be­cause there was al­ways some­thing more ur­gent.

It’s also not the typ­ing of code that I re­ally en­joy, nor is it the syn­tax or struc­ture or boil­er­plate that’s re­quired to build any­thing. It’s the fact you get to build some­thing out of noth­ing, writ­ing code was just how you got there. And with to­day’s tool­ing, that saves a ton of time.

AI re­ally has made web de­vel­op­ment fun again.

...

Read the original on ma.ttias.be »

6 209 shares, 17 trendiness

JeffGeerling.com has been Migrated to Hugo

Since 2009, this web­site has run on Drupal. Starting with Drupal 6, and pro­gress­ing through ma­jor site up­grades and mi­gra­tions to 7, 8, 9, and 10, I used the site as a way to dog­food the same CMS (Content Management System) I used in my day job for over a decade.

But as time pro­gressed—es­pe­cially af­ter com­plet­ing a gru­el­ing up­grade from Drupal 7 to 8—my en­thu­si­asm for main­tain­ing what’s now a more en­ter­prise-fo­cused Digital Experience Platform or DXP for a per­sonal blog has waned.

Not to men­tion, the blog is a pas­sion pro­ject. I use it as a scratch­pad for thoughts, and deeper dives for my YouTube videos. Time spent main­tain­ing a com­plex CMS is time I can’t spend ac­tu­ally writ­ing (not to men­tion time spent on every­thing else in life!).

I’ve moved other hobby sites to sta­tic host­ing. For older sites I don’t ac­tively up­date, I scrape and moth­ball them. But for sites I wanted to keep ac­tive, I con­verted them to Jekyll or Hugo, both of which are com­pe­tent and full-fea­tured mod­ern SSGs (Static Site Generators).

Jekyll is per­fect for the sta­tic sites I host for free on GitHub Pages, like the Raspberry Pi PCIe Database or Project MINI RACK, but I’m not a Ruby pro­gram­mer, so I like Hugo for any­thing I run on my own in­fra­struc­ture (like Geerling Engineering). It’s sim­pler to set up and a lit­tle faster.

Anyway, I’ve been work­ing on the mi­gra­tion in this GitHub is­sue, and there are bound to be mis­takes, bro­ken im­age ref­er­ences, and prob­a­bly some old URLs that just go poof!

I try to keep every­thing where it is, or add redi­rects. But with 20 years of bag­gage and 3500+ posts (many of those were in­di­vid­ual pho­tos con­verted into blog’ nodes in a prior up­grade… oops!), it’s hard to run a per­fect mi­gra­tion.

I’ve been writ­ing all my posts in Markdown since 2020, and even be­fore that, was draft­ing them in Markdown in Sublime Text, then ex­port­ing that to HTML via MarkdownPreview.

So hav­ing a tool (Hugo) that uses Markdown na­tively is a breath of fresh air.

Beyond that, I’ve grown fond of sticking to the de­faults’ over the years. On my ini­tial Drupal 6 site, I in­stalled some­thing like 30 mod­ules (plugins in Drupal par­lance), but al­most all of those mod­ules bit me in one way or an­other as I up­graded to Drupal 7, 8, 9, or 10…

Honestly, up­grad­ing from 8 to 9 to 10 was eas­ier than 6 to 7 and 7 to 8, sim­ply be­cause I had stripped my site down to the ba­sics.

However, in so do­ing, I also made my con­tent au­thor­ing ex­pe­ri­ence a bit hor­rid:

Write a blog post on my com­puter in a Markdown filePaste the Markdown con­tent into the body and add a ti­tlePut cur­sor where each pic­ture goes in the con­tent, scroll down to the up­loaded pic­ture, click Insert’ to in­sert the pre­for­mat­ted markup, and rinse-and-re­peat for all im­ages (sometimes up to 25-30 per post!).Clear out the Authored on’ field to make sure the date would up­date when I pub­lish the post­Tog­gle the Published’ op­tion and save the nodeRun an Ansible play­book to drop Drupal caches, Nginx caches, and trig­ger a Cloudflare purge of the rel­e­vant URLs (ongoing DDoSes since 2022 caused me to re­ally lock down my caching)…

It was a lot. Just to pub­lish a blog post—and none of that helped with writ­ing or be­ing cre­ative, it was just a bunch of work.

Yes, I could au­to­mate each step in Drupal. There are even mod­ules for Drupal, like Scheduler for sched­ul­ing posts and up­dat­ing pub­lish dates, and Cloudflare for purg­ing CDN cache… but you know what? I used to use those mod­ules, but af­ter four Drupal up­grade cy­cles, I was burned out on man­ag­ing patches for months, years, or in­def­i­nitely since some of the mod­ules took that long to have a sta­ble re­lease for [current Drupal ver­sion].

And don’t get me started on hav­ing to re­build en­tire con­tent au­thor­ing work­flows (e.g. WYSIWYG ed­i­tors, me­dia man­age­ment, and con­tent fields) every time a ma­jor Drupal ver­sion was re­leased! That spe­cific type of churn, thank­fully, is not as bad these days, but it was re­ally bad prior to Drupal 10 or so.

For Hugo, since my work­flow al­ready started with a Markdown file… the whole process is done af­ter step 1, ba­si­cally.

To pub­lish, I guess I do have to up­date the date in my post’s front­mat­ter, and change draft to false, but that’s about it. hugo && git com­mit -m Updated post.” && git push and the blog is up to date!

And for main­te­nance, don’t get me started on man­ag­ing Composer, Drush, PHP, MariaDB, Nginx, Cloudflare, etc. — for an en­ter­prise web­site, with mul­ti­ple con­tent work­flows, dozens or hun­dreds of users with RBAC, etc., sure, it’s fine. But for a blog where I just want to write and pub­lish, it has been wear­ing me down for the past few years.

Comments will be miss­ing site-wide ini­tially, as I’ve cho­sen to tackle a self-hosted sta­tic site com­ment­ing sys­tem in a phase two’. I love hav­ing com­ments en­abled, de­spite the mod­er­a­tion over­head, and don’t think blog­ging is the same with­out them.

I also loved hav­ing in­te­grated site search, since I use my blog as a pro­ject jour­nal, ref­er­enc­ing it of­ten. The Drupal site was in­te­grated into an Apache Solr search in­stance I also ran as part of Hosted Apache Solr… which I sun­set years ago at this point. So I’ll have to de­cide how I want to im­ple­ment search within Hugo.

...

Read the original on www.jeffgeerling.com »

7 197 shares, 37 trendiness

Claude Code On-The-Go

I run six Claude Code agents in par­al­lel from my phone. No lap­top, no desk­top—just Termius on iOS and a cloud VM.

flow­chart LR

A[Phone] –>|Termius + mosh| B[Tailscale VPN]

B –> C[Vultr VM]

C –> D[Claude Code]

D –>|PreToolUse hook| E[Poke web­hook]

E –>|Push no­ti­fi­ca­tion| A

The loop is: kick off a task, pocket the phone, get no­ti­fied when Claude needs in­put. Async de­vel­op­ment from any­where.

I pay only when work­ing. Two scripts han­dle life­cy­cle:

I also have an iOS Shortcut that calls the Vultr API di­rectly—start the VM from my phone be­fore I even open Termius.

The VMs pub­lic IP has no SSH lis­tener. All ac­cess goes through Tailscale’s pri­vate net­work. Defense in depth: cloud fire­wall blocks every­thing ex­cept Tailscale co­or­di­na­tion, lo­cal nfta­bles as backup, fail2ban for good mea­sure.

Termius han­dles SSH and mosh on iOS/​An­droid. Mosh is the key—it sur­vives net­work tran­si­tions. Switch from WiFi to cel­lu­lar, walk through a dead zone, put the phone to sleep. The con­nec­tion per­sists.

One gotcha: mosh does­n’t for­ward SSH agent. For git op­er­a­tions that need GitHub auth, I use reg­u­lar SSH in­side tmux.

The shell auto-at­taches to tmux on lo­gin. Close Termius, re­open hours later, every­thing’s still there.

Multiple Claude agents run in par­al­lel win­dows. C-a c for new win­dow, C-a n to cy­cle. Works well on a phone key­board.

This is what makes mo­bile de­vel­op­ment prac­ti­cal. Without no­ti­fi­ca­tions, you’d con­stantly check the ter­mi­nal. With them, you can walk away.

When Claude calls AskUserQuestion, the hook fires. A sim­ple script ex­tracts the ques­tion and POSTs to Poke’s web­hook:

I run Claude Code in per­mis­sive mode. The VM is iso­lated—no ac­cess to pro­duc­tion sys­tems, no se­crets be­yond what’s needed for de­vel­op­ment. Worst case: Claude does some­thing un­ex­pected on a dis­pos­able VM.

Cost con­trol adds an­other layer. The VM costs $0.29/hr. Even if some­thing runs away, the daily cap is bounded.

~/Code/myproject/ # main

~/Code/myproject-sidebar/ # fea­ture branch

~/Code/myproject-dark-mode/ # an­other fea­ture

Each work­tree gets its own tmux win­dow with a Claude agent. Port al­lo­ca­tion is hash-based—de­ter­min­is­tic from branch name, no con­flicts:

hash_­val = sum(ord(c) for c in branch_­name)

djan­go_­port = 8001 + (hash_val % 99)

Six agents, six fea­tures, one phone.

Review PRs while wait­ing for cof­fee. Kick off a refac­tor on the train. Fix a bug from the couch while watch­ing TV.

The pat­tern: start a task that will take Claude 10-20 min­utes, do some­thing else, get no­ti­fied, re­spond, re­peat. Development fits into the gaps of the day in­stead of re­quir­ing ded­i­cated desk time.

The setup took one Claude Code ses­sion to build—gave it my Vultr API key and ac­cess to gh, asked for a se­cure dev VM. Now I code from my phone.

...

Read the original on granda.org »

8 192 shares, 11 trendiness

The Gentle Seduction

First Published by Analog Magazine in 1989

He worked with com­put­ers; she worked with trees, and the flow­ers that took hold on the sides of the Mountain.

She was sur­prised that he was in­ter­ested in her. He was so smart; she was so … nor­mal. But he was in­ter­est­ing; he al­ways said some­thing new and dif­fer­ent; he was nice.

She was 25. He was older, al­most 33; some­times, Jack seemed very old in­deed.

One day they walked through the mist of a gray day by the Mountain. The for­est here on the edge of Rainier glowed in the mist, bright with lush greens. On this day he told her about the fu­ture, the fu­ture he was build­ing.

Other times when he had spo­ken of the fu­ture, a wild look had en­tered his eyes. But now his eyes were sharply fo­cused as he talked, as if, this time, he could see it all very clearly. He spoke as if he were de­scrib­ing some­thing as real and ob­vi­ous as the veins of a leaf hang­ing down be­fore them on the path.

Have you ever heard of Singularity?” he asked.

She shook her head. What’s that?”

Singularity is a time in the fu­ture. It’ll oc­cur when the rate of change of tech­nol­ogy is very great–so great that the ef­fort to keep up with the change will over­whelm us. People will face a whole new set of prob­lems that we can’t even imag­ine.” A look of great tran­quil­ity smoothed the ridges around his eyes. On the other hand, all our nor­mal, day to day prob­lems fade away. For ex­am­ple, you’ll be im­mor­tal.”

She shook her head with dis­taste. I don’t want to live for­ever,” she said.

He smiled, his eyes twin­kling. Of course you do, you just don’t know it yet.”

She shud­dered. The fu­ture scares me.”

There’s no rea­son to fear it. You’ll love it.” He looked away from her. His next words were bit­ter, but his tone was re­signed. It pisses me off that you’ll live to see it and I won’t.”

Speaking to the sor­row in his voice, she tried to cheer him. You’ll live to see it too,” she replied.

He shook his head. No. I have a bad heart. My fa­ther died young from a heart at­tack, and so did my fa­ther’s fa­ther. If I’m lucky, I have maybe 30 more years. It’ll take at least a hun­dred years for us to get to Singularity.

Then I’ll be dead be­fore it hap­pens, too. Good,” she said.

He chuck­led. No. You’ll live long enough, so that they’ll fig­ure out how to make you live long enough so that you can live longer.”

You’re still only 7 years older than I am.”

Ah, but you have your moth­er’s genes. She looks very young.”

She smiled, and changed the sub­ject. I’ll have to tell her you said that. She’ll like it.”

There was a long pause. Then she con­fessed, My grand­fa­ther is 92, and he still cuts the grass every week.”

She was adamant. I’ll live to be 80 or 90. I don’t want to live longer than that.”

Not if you’re crip­pled, of course not. But they’ll find ways of re­ju­ve­nat­ing you.” He laughed know­ingly. You’ll look older when you’re 60 than when you’re 120″ he said.

She just shook her head.

Another time, as they walked in the sun along the beach of Fox Island, he told her more about the fu­ture. You’ll have a head­band.” He ran his fin­gers across his fore­head; he squinted as the wind blew sand in his eyes. It’ll al­low you to talk right to your com­puter.”

She frowned. I don’t want to talk to a com­puter.”

Sure you do. At least, you will. Your com­puter will watch your baby all night long. If it sees some­thing wrong, it’ll wake you.” Wicked de­light widened his smile, and she knew he would now tell her some­thing out­ra­geous. While you’re lay­ing in bed with your eyes closed, you’ll look at your baby through your com­put­er’s TV cam­era to see if it’s some­thing se­ri­ous.”

Of course, there’s a tiny chance, re­ally tiny, that an ac­ci­dent could scram­ble your mem­o­ries.”

The thought made her dizzy with hor­ror. I would rather die.” She grabbed his arm and pulled him un­der the bridge, out of the wind. She shud­dered, though un­sure whether her chill came from the wind or the fear.

He changed his tack. Pointing at a scat­ter­ing of elab­o­rate sea­side man­sions across the wa­ter, he asked, Would you like to live in one of those?”

She stud­ied them. Maybe that one,” she said, point­ing at a beau­ti­ful old Victorian home. Or that one.” She pointed at an­other, very dif­fer­ent from the first, a se­ries of di­ag­o­nal slashes with huge win­dows.

Have you ever heard of nan­otech­nol­ogy?” he asked.

Well, with nan­otech­nol­ogy they’ll build these tiny lit­tle ma­chines–ma­chines the size of mol­e­cules.” He pointed at the drink in her hand. They’ll put a bil­lion of them in a space­ship the size of a Coke can, and shoot it off to an as­ter­oid. The Coke can will re­build the as­ter­oid into man­sions and palaces. You’ll have an as­ter­oid all to your self, if you want one.”

I don’t want an as­ter­oid. I don’t want to go into space.”

He shook his head. Don’t you want to see Mars?You liked the Grand Canyon; I re­mem­ber how you told me about it. Mars has huge gorges–they make the Grand Canyon look tiny. Don’t you want to see them? Don’t you want to hike across them?”

It took her a long time to re­ply. I guess so,” she ad­mit­ted.

I won’t tell you all the things I ex­pect to hap­pen,” he smiled mis­chie­vously, I’m afraid I’d re­ally scare you. But you’ll see it all. And you’ll re­mem­ber that I told you.” His voice grew in­tense. And you’ll re­mem­ber that I knew you’d re­mem­ber.”

She shook her head. Sometimes Jack was just silly.

They never made love, though of­ten, they fell asleep in each oth­er’s arms. Sometimes she won­dered why; she won­dered if he also won­dered why. Somehow it just did­n’t seem im­por­tant.

He seemed so at home in the deep for­est, he so clearly be­longed on the Mountain, she first thought they might stay to­gether for­ever. But one day she went with him to his of­fice. She watched as he worked with com­put­ers, as he worked with other peo­ple. He was as nat­ural a part of their com­puter world as he was a part of her Mountain world.

Working in that alien world, he was a dif­fer­ent per­son. In the woods, he was a calm source of sus­tain­ing strength. Here, he was a fever­ish in­struc­tor. His heart be­longed to the for­est, but his mind, she re­al­ized, be­longed to the ma­chines that would build his vi­sion.

One day he re­ceived a call. A dis­tant com­pany gave him an of­fer he could not refuse. So he went to California, to build great com­put­ers, to hurry his vi­sion to fruition.

She stayed by the Mountain. She walked the snows, and watched the birds fly over­head. Yet no bird flew so high that she could not climb the slopes of Rainier un­til she stood above them.

He would come to visit on week­ends some­times, and they would back­pack, or ski cross coun­try. But his vis­its be­came less fre­quent. He would write in­stead. That too de­creased in reg­u­lar­ity. One let­ter was the last, though nei­ther of them knew it at the time.

A year passed. And by then, it just did­n’t seem to mat­ter.

She mar­ried a for­est ranger, a bright, quiet man with dark eyes and a rugged face. They had three small chil­dren and two large dogs, friendly dogs with thick soft fur. She loved all the mem­bers of her fam­ily, al­most all the time; it was the theme that never changed though she thought about dif­fer­ent things at dif­fer­ent times.

Her chil­dren grew up and moved away.

Erich, the beau­ti­ful red chou, went to sleep one night and never awak­ened.

A ter­ri­ble avalanche, from a seem­ingly safe slope, fell down the Mountain and buried a climb­ing team, her hus­band among them.

Haikku, her mighty and faith­ful akita,whim­pered in his old age. He crooned his apol­ogy for leav­ing her alone, and that night he joined Erich and her hus­band.

She was 82. She had lived a long and happy life. She was not afraid to die. But she stood out­side in the snow and faced a ter­ri­ble de­ci­sion.

Overnight, a thick blan­ket of new white pow­der had fallen, bury­ing her side­walk. Standing in the snow, she stared at a me­chan­i­cal beast her chil­dren had given her years be­fore. It rep­re­sented one pos­si­ble choice.

In one hand she held a shovel. In the other hand she held a small cap­sule. The cap­sule was an­other gift her chil­dren had given her. They had begged her to take it. Until now, she had re­fused. The cap­sule rep­re­sented an­other choice.

Her back was aching. It was an ache that some­times ex­panded, shoot­ing spikes of pain down her legs. Today the pain was great; she could not shovel the side­walk.

The me­chan­i­cal beast was a ro­bot, a fully au­to­matic snow re­mover. She could just flip a switch and it would hurl the snow away, but that seemed grotesque; the noise would be ter­ri­ble, the mounds of thought­lessly dis­carded snow would re­main as an un­seemly scar un­til late spring.

She opened her hand and looked at the cap­sule. It was not a pill to make her younger; that much her chil­dren had promised her. They knew she would re­ject such a thing out of hand. But the mil­lions of tiny ma­chines tucked in­side the cap­sule would dis­perse through­out her body and re­pair every trace of dam­age to her bones. They would also re­build her sag­ging mus­cle tis­sue. In short, the pill would cure her back and make the pain go away.

The thought of all those lit­tle ma­chines in­side her made her shud­der. But the thought of the au­to­matic snow re­mover made her sick.

She went back in­side the house to get a glass of wa­ter.

In a few days her back felt fine; her healthy mus­cles gave her a feel­ing of new vigor, and the vigor gave rise to a yearn­ing to go out and do things that she had not con­sid­ered for many years. She started to climb the Mountain, but it was too much for her: she huffed and puffed and had to go home. Annoyed, she went to the drug store and bought an­other cap­sule, one that re­stored her cir­cu­la­tory sys­tem and her lungs. Her next as­sault on the Mountain car­ried her as far as she dared, and the steady beat of her heart urged her to go on de­spite the crum­bling snow.

But she was get­ting in­creas­ingly for­get­ful. Things that had hap­pened years ear­lier were clear in her mind, but she could not re­mem­ber what she needed at the store. One day she for­got her daugh­ter’s tele­phone num­ber, and found that she had for­got­ten where she had mis­placed the phone book. The store had an­other cap­sule that tight­ened up her neural cir­cuitry. After tak­ing it, she dis­cov­ered a side ef­fect no one had both­ered to men­tion. The pill did not merely make her mem­ory ef­fec­tive again; rather, it made her mem­ory per­fect. With a brief glance through the pages of the phone book, she found she no longer needed it. She shrugged and con­tin­ued on with her life.

One day as she skied across the slopes, a stranger passed her go­ing the other way. He was tall and rugged, and he re­minded her of her hus­band. She was an­noyed that he did not even look at her, though she had smiled at him; when she looked in the mir­ror upon re­turn­ing home, she un­der­stood why. She was 95 years old; she looked like an old woman. It was ridicu­lous; for­tu­nately it was eas­ily fixed.

When she turned 115 she sta­bi­lized her phys­i­cal ap­pear­ance. Thereafter, she al­ways ap­peared to be about the age of 32.

She still owned the snug lit­tle house she thought of as home. But she slept more of­ten in the tent she car­ried in her pack. Built with nanoma­chined equip­ment, the pack was lighter than any other she had ever owned, yet it was im­pos­si­bly strong. All her tools per­formed feats she would once have thought mirac­u­lous, and none weighed more than a pound. She lived in great com­fort de­spite the in­her­ent rig­ors of the glac­ier-crusted slopes.

One day, she was climb­ing along the an­cient trail from Camp Muir to­ward the sum­mit, cross­ing the ridges to reach Disappointment Cleaver. As she stepped over the last ridge to the broad flat in front of the Cleaver, she saw a man stand­ing alone. He was star­ing up the steep ice flows over­head. He stepped back­ward, and back­ward, and turned to walk briskly in her di­rec­tion. She con­tin­ued for­ward to pass him, but he cried out, Stop!”

She obeyed the fear in his voice. He paused, and his eyes came un­fo­cussed for a mo­ment. He pointed to the right of the ridge she had just crossed, a fin of rock ris­ing rapidly along the moun­tain’s edge. Up there,” he said, Quickly.” He broke into a hob­bling run across snow that some­times col­lapsed un­der his heavy step. She fol­lowed, her adren­a­lin ris­ing with her be­wil­der­ment.

A mas­sive Crack! filled the air. Far above the Cleaver, an over­hang­ing ledge of ice snapped off and fell with an ac­ro­bat’s grace­ful tum­bling mo­tion to the flat where they had just been stand­ing. The mass qual­i­fied as a large hill in its own right. When it landed it broke into a thou­sand huge pieces. Some of the pieces ground each other to pow­der, while oth­ers bounced off the flat, down an­other precipice of sev­eral thou­sand feet, to crash again in a duller ex­plo­sion of sound.

The ice fall was an ex­tra­or­di­nary event to wit­ness un­der any cir­cum­stance; the nar­row­ness of es­cape from death that ac­com­pa­nied it over­layed the ex­pe­ri­ence with a re­li­gious awe.

She heard the man pant­ing next to her. She turned to study him more care­fully.

He was un­re­mark­able for a moun­taineer; his lean form sup­ported long straps of hard mus­cle, and the re­flected sun from the glac­i­ers had given him a cof­fee-col­ored tan. Then she no­ticed the sweat­band across his head. It was not just a sweat­band: she could see from the stretch marks that a se­ries of thin disks ran across within the cot­ton lay­ers. She re­al­ized he was wear­ing a nec­tion, a head­band to con­nect his mind with dis­tant com­put­ers.

She re­coiled slightly; he smiled and touched his fore­head. Don’t be too up­set,” he said, my head­band just saved your life.”

She stut­tered. I was­n’t up­set,” she said, though she knew that he knew she was ly­ing. I’ve just never seen one up close be­fore.”

It was true. Her grand­chil­dren told her that nec­tions were quite com­mon in space, but on Earth they were al­most il­le­gal. It was so­cially un­ac­cept­able to wear one, and when the po­lice saw a nec­tion-wear­ing per­son they would use any ex­cuse to has­sle the in­di­vid­ual. But there were no spe­cific laws against them.

When her grand­chil­dren had told her that they wore head­bands all the time, she had tried only briefly to dis­suade them; she had spent more time lis­ten­ing to their de­scrip­tions of the head­band’s ca­pa­bil­i­ties. Her grand­chil­dren’s de­scrip­tion sounded con­sid­er­ably dif­fer­ent from the list of dan­gers usu­ally de­scribed on the news.

The man who had saved her life watched her for sev­eral more sec­onds, then ap­par­ently made up his mind about some­thing. You re­ally ought to get one your­self, you know. Do you re­al­ize how dan­ger­ous this moun­tain is? And it’s get­ting more dan­ger­ous every year.”

She started to tell him that she knew per­fectly well how dan­ger­ous it was–then stopped, think­ing back over the years, re­al­iz­ing that it had, by grad­ual de­grees, grown worse every year.

With my head­band, I see things bet­ter,” he ex­plained. I con­fess I don’t un­der­stand why very well–I mean, it does­n’t af­fect my eye­sight. But I no­tice more things about what I see, and I can get a view of what the ex­tra things mean–like how that piece of ice would fall, and more or less when.”

She nod­ded her head, but her mind was dis­tracted. The Mountain was chang­ing! The Mountain was get­ting more dan­ger­ous! The rapid al­ter­na­tion of clear, sunny days with cool, misty days had be­come more vig­or­ous over the course of the last 50 years, lead­ing to more weak lay­ers and ice faults. She had never re­ally no­ticed un­til now.

Then the full im­pact of her sav­ior’s words struck her–she held her hands to her throat as she con­sid­ered how her hus­band had died. She re­al­ized that, with a nec­tion, his death could have been pre­vented.

She smiled at the man. They talked; she in­vited him to din­ner at Alexander’s.

When she re­turned home, she started search­ing through elec­tronic equip­ment cat­a­logs. If she bought one mail or­der and wore it only while hik­ing, there was no rea­son for any of her friends ever to know.

It was a sim­ple white head­band, soft ab­sorbent cot­ton. She slipped it on her head, ex­pect­ing to feel some­thing spe­cial, but noth­ing hap­pened. She started to clean the house, still wait­ing for some­thing to hap­pen. It never did. Eventually she sat down and read the in­struc­tions that had come with the head­band.

The in­struc­tions told her to start with a sim­ple re­quest, and to vi­su­al­ize her­self pro­ject­ing the re­quest at her fore­head. She pro­jected the re­quest, 2 times 2?” just above her eyes. Nothing seemed to hap­pen. She knew the an­swer was 4.

She tried again, and this time she no­ticed a kind of echo–she knew the an­swer was 4, but the thought of the an­swer came to her twice, in rapid suc­ces­sion. The next time she tried it, she no­ticed that the echo seemed to come from her fore­head.

Next she pro­jected a re­quest to di­vide 12345 by 6789. She did­n’t know the an­swer–but wait, of course she did, it was 1.81838. Of course, she did­n’t know the an­swer to many dec­i­mal places–but as she thought about it, she re­al­ized the next digit was 2, the next was 6, then at an ac­cel­er­at­ing pace more dig­its roared from her mem­ory–she shook her head, and the stream stopped. She took the head­band off, shak­ing a lit­tle. She did­n’t try it again un­til the next day.

A week later, she hiked past Camp Schurman and peered up the slope. She pro­jected her view of the slope through her fore­head to study the pat­terns of snow and ice.

It did in­deed look dif­fer­ent as she looked at it this way. She had a sen­sa­tion sim­i­lar to that of look­ing at the edges of a cube on a sheet of pa­per: at one mo­ment, the lines formed a cube with the top show­ing. The next mo­ment it was an al­ter­nate cube with the bot­tom ex­posed. She could flip the cube, or at least the way she looked at it, at will.

In the same man­ner she could now see pat­terns of slip­page in the lay­ers of ice crys­tals; then she would flip the im­age and it was just snow, the beau­ti­ful work of na­ture that she had loved all her life.

For a mo­ment she wished she could see it from above as well–and her heart skipped a beat as the wish came true. Suddenly she was look­ing down from a great height. She saw the long curves of shad­ows across the snow from high above, and she saw the shorter but dis­tinc­tive shadow of a woman with a pack stand­ing on the snow field. She threw the head­band to the ground even as she re­al­ized what she had just seen: a view of the Mountain from a satel­lite pass­ing by.

She stared at the white head­band, al­most in­vis­i­ble in the white snow, for a long time. She felt dis­taste, won­der, fear, and cu­ri­ousity. Curiousity fi­nally won out. She twisted the head­band back on. She blinked her mind’s eye, blink­ing from her own eyes to the satel­lite’s eyes and back again, a mo­men­t’s taste of the new sen­sa­tion.

Vertigo struck her. Though the satel­lite was in­ter­est­ing, it was not com­fort­able. She would not look at the world from a satel­lite’s height of­ten, but it was yet an­other life-sav­ing form of sight: from a dis­tance, it was easy to spot a de­pres­sion in the snow that might sig­nal an un­der­ly­ing crevasse, even though the de­pres­sion was too shal­low to be seen close up. Such crevasses were in­vis­i­ble un­til one stepped through to a long fa­tal plunge to the Mountain’s heart.

The head­band was so clearly a life sav­ing tool, why were peo­ple so set against it? Why did some of her friends sup­port laws pro­scrib­ing it?

It did­n’t make any dif­fer­ence; she had no need of it ex­cept here on the Mountain.

Though the fight over the head­band’s le­gal sta­tus did not at first in­ter­est her, it be­came an in­creas­ing im­ped­i­ment to her life. The head­band was quite use­ful in a num­ber of ways; though each in­di­vid­ual use was triv­ial, in sum they qual­i­ta­tively ef­fected her life. She stopped track­ing her check­book; it was all in her head, all the trans­ac­tions, the cur­rent bal­ance, and even the en­cum­brances. When she awoke in the morn­ing she could turn on the cof­fee pot if she wanted to, with­out get­ting up.

She wore her head­band while hik­ing, and while work­ing around her house; but she dared not wear it to work. One day an ecol­o­gist asked her a ques­tion about the mar­mots that in­hab­ited the park. She grew an­gry as she had to man­u­ally root through the com­puter sys­tems try­ing to find the an­swer, for she knew that the an­swer was avail­able for the mere think­ing about it if she could wear her head­band. That night she stopped at the drug­store and bought two more cap­sules.

She swal­lowed one. This cap­sule was nas­tier than the oth­ers she had taken in ear­lier years. Before, the nanoma­chines she had swal­lowed had gone through her body, fix­ing what was not right, then flush­ing them­selves out again. But the ma­chines in this one would build, just un­der her fore­head, a sub­cu­ta­neous nec­tion.

The other cap­sule would dis­solve the nec­tion away if she de­cided she did­n’t like it.

When she awoke the next morn­ing she was very hun­gry. She felt her fore­head, but there was­n’t any­thing there.

The next morn­ing she felt her fore­head again, and it was … dif­fer­ent. She looked in the mir­ror; with the flick­er­ing dou­ble vi­sion of her eyes and the analy­sis from her fore­head, she could see on the one hand that she looked the same as al­ways. Yet on the other hand, there were curves there she had­n’t no­ticed be­fore. When she went in to work, one man com­pli­mented her on her new hair color.

No one else com­mented un­til her boss ar­rived. When he en­tered the re­cep­tion area and looked at her, his eyes lit up, and he laughed.

She looked at him with mild an­noy­ance. Then she no­ticed, again with her dou­ble vi­sion, that there were very shal­low curves in his fore­head.

...

Read the original on www.skyhunter.com »

9 181 shares, 10 trendiness

Maybe Comments SHOULD Explain 'What'

People say Comments should ex­plain why, not what.” I feel like start­ing a flame war to­day so I’m go­ing to ar­gue that com­ments should ex­plain what’ too. Please don’t use this as jus­ti­fi­ca­tion to write bad code, okay? Okay.

First of all, why should­n’t com­ments ex­plain what’? If you need com­ments to ex­plain what’s go­ing on, it sug­gests your code is un­clear. If I write

//weight, ra­dius, price

w = 10, r = 9, p = 1

That’s not as clear as say­ing

weight = 10, ra­dius = 9, price = 3

But it’s ob­vi­ous that w is weight!” Sure, if you’re see­ing those lines back-to-back. But pre­sum­ably you’re ini­tial­iz­ing the vari­able to use it, which means that it’s go­ing to ap­pear later. When you see w later in the body, you need to go back and check what it is. That’s a frus­trat­ing con­text switch and you may skip it, pos­si­bly as­sum­ing that w is… width. Then bad things hap­pen. So com­ments are not a sub­sti­tute for clean code.

Okay, so why should com­ments ex­plain why? Some peo­ple ar­gue that we should in­stead store the why’ in com­mit mes­sages or tests. Most peo­ple feel icky about this, though. Given:

// Clear twice to deal with bug ABC in li­brary XYZ, see [link]

XYZ.clear(); XYZ.clear();

Would you pre­fer that com­ment be re­moved and placed in the com­mit mes­sage? Then if you want to learn why XYZ.clear() is re­peated twice, you have to dig up the com­mit. That can be a dif­fi­cult and te­dious job, es­pe­cially if the line was re­for­mat­ted, moved be­tween files, any­thing that makes git blame not work. Searching all that is a con­text switch and you may skip it, pos­si­bly as­sum­ing that it’s a bug you can re­move. Then bad things hap­pen.

Both of these cases share the same prob­lem: look­ing things up is hard. Best case it’s a con­text switch that takes time away from un­der­stand­ing the prob­lem. Worst case you don’t look it up and make a po­ten­tially-dan­ger­ous as­sump­tion. It’s bet­ter to keep the in­for­ma­tion in the ex­act same place that you need it, whether that’s via de­scrip­tive code or com­ments over com­mits.

Now for the weird part. What if your de­scrip­tive code forces a con­text switch? Let’s take the code from Bob Martin’s Extract Till You Drop.

To make it more un­der­stand­able, he re­places it with this:

So much bet­ter, right?! re­place is now two lines in­stead of ten. But now there’s six other meth­ods you have to read to un­der­stand how the class works. But it’s eas­ier to fol­low.” Not if I’m try­ing to track down a bug and I have to keep scrolling up and down, jump­ing from method to method to un­der­stand the whole. Is that re­ally so much bet­ter than us­ing com­ments?

I think that’s more un­der­stand­able than ei­ther the orig­i­nal case or the clean code case, be­cause you don’t have to con­text switch to a dif­fer­ent method to un­der­stand what’s go­ing on. Obviously this is­n’t al­ways the case, and of­ten com­ments are su­per­flu­ous. I’m just say­ing that there are at least a few cases where writ­ing a what’ com­ment is the right choice, so we should­n’t re­ject them out-of-hand.

...

Read the original on www.hillelwayne.com »

10 177 shares, 17 trendiness

I charged $18,000 for a Static HTML Page

Not too long ago, I made a liv­ing work­ing as a con­trac­tor where I would hop from pro­ject to pro­ject. Some were short term where I would work for a week and quickly de­liver my ser­vice. Others lasted a cou­ple months where I would make enough money to take some time off. I pre­ferred the short ones be­cause they al­lowed me to charge a much higher rate for a quick job. Not only I felt like my own boss, but I also felt like I did­n’t have to work too hard to make a de­cent liv­ing. My high­est rates were still rea­son­able, and I al­ways de­liv­ered high qual­ity ser­vice. That was un­til I landed a gig with a large com­pany.

This com­pany con­tacted me in ur­gency and the man­ager told me they needed some­one right away. Someone who re­quired min­i­mum train­ing for max­i­mum per­for­mance. For bet­ter or worse, that was my motto. This pro­ject was ex­actly the type of work I liked. It was short, fast, and it paid well.

After ne­go­ti­at­ing a de­cent rate, I re­ceived an email with the in­struc­tions. They gave me more con­text for the ur­gency. Their de­vel­oper left with­out prior warn­ing and never up­dated any­one on the sta­tus of his pro­ject.

We need your full un­di­vided at­ten­tion to com­plete this pro­ject. For the du­ra­tion of the con­tract, you will work ex­clu­sively with us to de­liver re­sult in a timely man­ner. We plan to com­pen­sate you for the trou­ble.

The in­struc­tions were sim­ple: Read the re­quire­ments then come up with an es­ti­mate of how long it would take to com­plete the pro­ject. This was one of the eas­ier pro­jects I have en­coun­tered in my ca­reer. It was an HTML page with some mi­nor an­i­ma­tions and a few em­bed­ded videos. I spent the evening study­ing the re­quire­ments and sim­u­lat­ing the im­ple­men­ta­tion in my head. Over the years, I’ve learned not to write any code for a client un­til I have a guar­an­tee of pay.

I de­ter­mined that this pro­ject would be a day’s worth of work. But to be cau­tious, I quoted 20 hours with a rough to­tal of $1500. It was a sin­gle HTML page af­ter all, and I can only charge them so much. They asked me to come on site to their satel­lite of­fice 25 miles away. I would have to drive there for the 3 days I would be work­ing for them.

The next day, I ar­rived at the satel­lite of­fice. It was in a shop­ping cen­ter where a se­cret door led to a se­cret world where a few work­ers where churn­ing qui­etly in their cu­bi­cles. The re­cep­tion­ist pre­sented me with a brand new MacBook Pro that I had to set up from scratch. I do pre­fer us­ing a com­pa­ny’s lap­top be­cause they of­ten re­quire con­trac­tors to in­stall sus­pi­cious soft­ware.

I spent the day down­load­ing my toolkit, set­ting up email, ssh keys, and re­quest­ing in­vites to ser­vices. In other words, I got noth­ing done. This is why I quoted 20 hours, I lost 8 hours of my es­ti­mated time do­ing busy work.

The next day, I was ready to get down to busi­ness. Armed with the MacBook Pro, I sent an email to the man­ager. I told him that I was ready to work and that I was wait­ing for the afore­men­tioned as­sets. That day, I stayed in my cu­bi­cle un­der a softly buzzing light, twid­dling my fin­gers un­til the sun went down.

I did the math again. According to my es­ti­mate, I had 4 hours left to do the job, which was not so un­re­al­is­tic for a sin­gle HTML page. But need­less to say, the next day, I spent those re­main­ing 4 hours in a com­pany spon­sored lunch where I ate very well and min­gled with other em­ploy­ees.

When the time ex­pired, I made sure to send the man­ager an­other email, to let him know that I had been pre­sent in the com­pany only I had not re­ceived the as­sets I needed to do the job. That email, of course, was ig­nored.

The fol­low­ing Monday, I hes­i­tantly drove the 25 miles. To my sur­prise, the man­ager had come down to the satel­lite of­fice where he en­thu­si­as­ti­cally greeted me. He was a nice easy-go­ing guy in his mid thir­ties. I was con­fused. He did­n’t have the ur­gency tone he had on the phone when he hired me. We had a friendly con­ver­sa­tion where no work was men­tioned. Later, we went down to lunch where he paid for my meal. It was a good day. No work was done.

Call me a crea­ture of habit, but if you feed me and pam­per me every­day, I get used to it. It turned into a rou­tine. I’d come to work, spend some time on­line read­ing and watch­ing videos. I’d send one email a day, so they know I am around. Then I’d go get lunch and hang­out with whomever had an in­ter­est­ing story to share. At the end of the day, I’d stand up, stretch, let out a well de­served yawn, then drive home.

I got used to it. In fact, I was ex­pect­ing it. It was a lit­tle dis­ap­point­ing when I fi­nally got an email with a link that pointed to the as­sets I needed for the job. I came back down to earth, and put on my work­ing face. Only, af­ter spend­ing a few min­utes look­ing through the zip file, I no­ticed that it was miss­ing the bulk of what I needed. The de­signer had sent me some Adobe Illustrator files, and I could­n’t open it on the MacBook.

I replied to the email ex­plain­ing my con­cerns and bun­dled a few other ques­tions to save time. At that point, my quoted 20 hours time had long ex­pired. I wanted to get this job over with al­ready. Shortly af­ter I clicked on send, I re­ceived an email. All it said was: Adding Alex to the thread,” and Alex was CC’d to the email. Then Alex replied where he added Steve to the thread. Steve replied say­ing that Michelle was a de­signer and she would know more about this. Michelle auto re­sponded say­ing that she was on va­ca­tion and that all in­quiries should be di­rected to her man­ager. Her man­ager replied ask­ing Who is Ibrahim?” My man­ager replied ex­cus­ing him­self for not in­tro­duc­ing me.

As a con­trac­tor, I am usu­ally in and out of a com­pany be­fore peo­ple no­tice that I work there. Here, I re­ceived a flood of emails wel­com­ing me aboard. The chain of emails con­tin­ued for a while and I was forced to an­swer to those aw­fully nice mes­sages. Some peo­ple were ea­ger to meet me in per­son. They got a lit­tle dis­ap­pointed when I said that I was all the way down in California. And jeal­ous, they said they were jeal­ous of the beau­ti­ful weather.

They used cour­tesy to ig­nore my emails. They used CC to de­flect my ques­tions. They used spam to dis­miss any­thing I asked. I spent my days like an ar­chae­ol­o­gist dig­ging through the deep trenches of emails, hop­ing to find an­swers to my ques­tions. You can imag­ine the level of im­pos­tor syn­drome I felt every time I re­mem­bered that my only task was to build a sin­gle sta­tic HTML page. The over­es­ti­mated 20 hours pro­ject turned into a 7 weeks ad­ven­ture where I en­joyed free lunches, drove 50 miles every­day, and dug through emails.

When I fi­nally com­pleted the pro­ject, I sent it to the team on github. All great ad­ven­tures must come to an end. But shortly af­ter, I re­ceived an in­vi­ta­tion to have my code re­viewed by the whole team on Google Hangout. I had spent more than a month build­ing a sin­gle sta­tic HTML page and now the en­tire team would have to cri­tique my work? In my de­fense, there was also some JavaScript in­ter­ac­tions, and it was re­spon­sive, and it also had CSS an­i­ma­tions… Impostor.

Of course, the video meet­ing was resched­uled a few times. When it fi­nally hap­pened, my work and I were not the sub­ject of the meet­ing. They were all sit­ting in the same room some­where in New York and talked for a while like a tight knit group. In fact, all they ever said about the pro­ject was:

Person 1: Hey is any­one work­ing on that spon­sored page?

Person 2: Yeah, I think it’s done.

Person 1: Great, I’ll merge it tonight.

When I went home that night, I re­al­ized that I was fac­ing an­other chal­lenge. I had been work­ing at this com­pany for 7 weeks, and my orig­i­nal quote was for $1,500. That’s roughly the equiv­a­lent of $11,100 a year or $214 a week. Or even bet­ter, it was $5.35 an hour.

This barely cov­ered my trans­porta­tion. So, I sent them an in­voice where I quoted them for 7 weeks of work at the orig­i­nal hourly rate. The to­tal amounted to $18,000. I was ashamed of course, but what else was I sup­posed to do?

Just like I ex­pected, I got no re­ply. If there is some­thing that all large com­pa­nies have in com­mon, it’s that they are not very ea­ger to pay their bills on time. I felt like a cheat charg­ing so much for such a sim­ple job, but this was not a char­ity. I had been dri­ving 50 miles every­day to do the job, if the job was not get­ting done it was not for my lack of try­ing. It was for their slow re­sponses.

I got an an­swer the fol­low­ing week. It was a cold email from the man­ager where he broke down every day I worked into hourly blocks. Then he high­lighted those I worked on and marked a one hour lunch break each day. At the end he made some cal­cu­la­tions with our agreed upon hourly rate.

Apparently, I was wrong. I had mis­cal­cu­lated the to­tal. After ad­just­ment, the to­tal amount they owed me was $21,000.

Please con­firm the read­justed hours so ac­count­ing can write you a check.

I am writ­ing a book! Join me in my jour­ney.

...

Read the original on idiallo.com »

To add this web app to your iOS home screen tap the share button and select "Add to the Home Screen".

10HN is also available as an iOS App

If you visit 10HN only rarely, check out the the best articles from the past week.

If you like 10HN please leave feedback and share

Visit pancik.com for more.