Week 2: When Discipline Takes Over
Week 2: When Discipline Takes Over
The weekend passed. Monday brought reality back.
My alarm went off at 7:00am. Winter quarter had started.
Last week, my schedule was flexible. Internship work I could move around. Time to think. Space to breathe.
Now: 8am to 6pm, packed. Four classes, labs, discussion sections, internship work squeezed into gaps. And somewhere inside all of that, 2:00-4:30pm every single day, deep work at Starbucks.
I could have rescheduled. Found time that made more sense.
I didn't.
Every day that week, I finished class, walked to Starbucks, sat down at 2pm, and stayed until 4:30. Tired. Distracted. Sometimes half-asleep.
This is where I usually start rearranging things.
I kept showing up.
Day 6: Monday - UDP Begins
Monday afternoon. First day with the new schedule. I was already tired from calculus and physics, but I sat down and opened Beej's Guide to the UDP section.
UDP felt different. Simpler.
No connection establishment. No three-way handshake. No bind-listen-accept dance. Just sendto() and recvfrom(). Throw a packet at an address. Hope it arrives.
The concepts clicked faster than TCP did. Maybe because I already understood sockets. Maybe because connectionless is genuinely simpler.
I built a UDP client and server from memory. I had to reference syntax constantly. I haven't internalized C yet. But the logic came from my head.
The gap between understanding and doing was shrinking, but still there.
Day 7: Tuesday - Packets Disappear
Tuesday I simulated packet loss.
Added a random number generator to my client. 50% of the time, don't send the packet. Just skip it.
Ran both programs and watched what happened.
Half my messages never arrived. The client thought it sent them. The server never knew they existed. Both sides just moved on.
Strange watching data vanish. In TCP, every byte mattered. Delivery was guaranteed. Here? Packets just disappeared.
That's when I understood why games use UDP.
Imagine a player running across a map. Their position updates 60 times per second. If packet #47 gets lost, so what? Packet #48 arrives 16 milliseconds later with the current position. Why stop everything to retransmit outdated data?
TCP would wait. Retry. Guarantee delivery. But by the time packet #47 arrives, the player has moved five steps forward. That old position is worthless.
UDP taught me that perfection is the enemy of performance. In a game, a perfect packet that arrives late is a failure.
This was the last day things felt clean.
Day 8: Wednesday - The Gap
Wednesday I tried to implement ACK packets for UDP.
The concept was simple: add sequence numbers to messages so the server can acknowledge them. Client sends message, waits for ACK. No ACK? Resend.
Basic reliability on top of an unreliable protocol. I wanted to build it myself.
My understanding was ahead of my hands.
Not because of UDP. Because of C.
I needed to pack a sequence number and a message into a single buffer. Send both together as one packet. On the receiving side, unpack the number and extract the message separately.
In Python, this is trivial. In C++ with strings, it's simple. In C? I had no idea.
I stared at my char[] buffer. How do I add an integer to it? How do I append the message after? Convert the integer to a string first? Pack it as raw bytes?
I tried for an hour. Looked at Beej's serialization examples. Saw functions using bit shifts and hex masks. Didn't understand any of it.
The voice in my head started: "Just use sprintf() and move on. Or ask AI to write this part. It's not important. You understand the concepts. That's what matters."
But that's the pattern I'm trying to break.
My brain understood the networking logic, but my hands didn't know how to speak the language. In C, you don't just "add" data. You fight for every byte of memory.
I needed to understand C buffers. Memory. Bytes. How data is actually stored and manipulated.
That meant stopping network programming to learn C fundamentals.
It felt like slamming the brakes on everything I'd built so far. But the gap was real. I couldn't ignore it.
Day 9: Thursday - 3:01pm
Thursday was the hardest day so far.
One class that morning. Data Structures at 9:30am.
The day felt longer. Unstructured. I had homework piling up. Problem sets. Code to debug. Time that felt both free and obligated.
I'd been working on homework since 10:30am. Staring at my laptop. Making slow progress.
By 2pm, I was already tired. Not from classes, but from the weight of unfinished work.
I walked to Starbucks anyway.
I sat at my usual spot at the center table. It's always busy. People walking past constantly.
Usually that helps. The social pressure keeps me focused.
Today it didn't matter.
I opened my laptop. Pulled up documentation on bits and bytes. Binary representation. 2's complement. Bit shifting.
It was the kind of learning that offers no dopamine. No 'Run' button, no green text in the console. Just the silent friction of a mind trying to expand.
I started reading about how integers are stored in memory. How data can be packed efficiently. How to work with information at the byte level.
My eyes started closing.
I'd be reading a paragraph and my eyes would shut. I'd catch myself, force them open, start reading again. Then they'd close again.
I can vividly recall it happening four or five times. Jolt. Reset. Read. Repeat.
My eyes ached. My head hurt. I could hear conversations around me more clearly than I could focus on the words in front of me.
Around 2:45pm I gave up trying to read and just stared at my laptop.
3:01pm
I opened Claude: "I feel so tired and bored. I want to sleep more than anything right now."
I wasn't looking for code. I was looking for a witness.
Every part of me wanted to leave. My mind was already writing the justification:
"I'm too exhausted. It's beyond my control. I need a 20-minute nap. Then I'll be fresh."
Logical. Reasonable. Compelling.
It was also an excuse.
89 minutes left in my session.
I told myself: 30 more minutes. You can do anything for 30 minutes.
I kept reading.
How integers are stored. How you can shift and extract bytes. How to pack data efficiently instead of storing it as text.
I read about 2's complement—how negative numbers work in binary. How computers actually represent data.
I wasn't enjoying it. I wasn't excited. I was just reading words and trying to understand them.
Somewhere around 3:30pm, I forgot I was going to take a break.
I kept going. The concepts started connecting. Not clicking—they still felt foggy—but connecting. I could see how to pack data efficiently. Why you'd want to work at the byte level.
4:30pm arrived. I closed my laptop.
I walked out exhausted. But not defeated.
I'd wanted to quit more than any day yet. More than Week 1's Day 4. More than Day 5 in my hometown.
Thursday at 3:01pm, I was convinced I was too tired to work. My mind told me it was beyond my control.
I stayed anyway.
Day 10: Friday - The Breakthrough
Friday morning. Four classes back-to-back. Math, Physics with lab, Digital Systems, discussion section.
By 2pm when I walked into Starbucks, I hadn't eaten since breakfast. Exhausted.
It was a different exhaustion. On Thursday, it came from guilt and wasted time. On Friday, it was earned.
The binary theory I'd choked down on Thursday had finally settled. I understood bits and bytes now. Not perfectly. But enough.
I sat down. Opened my UDP code. Started creating functions.
First, packing. A function to take an integer and write it into a buffer byte by byte using bit shifts. I copied Beej's first example to understand the pattern. Then closed the reference and wrote the 32-bit and 64-bit versions myself from memory.
Each line shifted the integer by a different amount to extract one byte. The pattern was clear now.
I built a custom append function to add data after the sequence number. Wrote a header file. Used it across both client and server files.
Then I implemented the ACK system I'd been trying to build since Day 6.
Client sends a message with a sequence number. Server acknowledges it. No acknowledgment? Resend. Basic reliability on top of unreliable UDP.
I simulated packet loss. Set it to drop half the packets randomly.
Ran both programs.
Watched a packet drop. Watched the client wait. No ACK. Resend. ACK arrives. Move to next message.
It worked.
Then I tried to print the full buffer to debug something. Nothing showed up. The message was missing.
Ten minutes of being confused. Then I realized: the sequence number wasn't stored as text. It was raw byte data.
I'd been reading about bytes for hours yesterday. But now I was seeing it. Understanding the theory had let me recognize what was actually happening.
I changed my code to print only the message portion after unpacking the sequence number separately. Suddenly everything appeared.
From there, I was just building. Experimenting. Having ideas and implementing them.
I'd try something—it would work or break. If it broke, I'd figure out why. Add a fix. Try again.
The friction was gone. I wasn't fighting the language anymore; I was finally using it.
I wanted the client to track acknowledged messages. I built it. Wanted to see dropped packets resend automatically. I built it. Wanted better output showing what was happening. I built it.
All the custom buffer functionality was mine. Not copied. Not following a tutorial. Mine.
The logic was mine. The structure was mine. The solution was mine.
Around 4pm, I sat back and watched my programs run. Client sending messages with sequence numbers. Server acknowledging them. Packets dropping and retransmitting. Everything working.
It felt like art.
A glimpse of what mastery might feel like. Still just UDP basics. Still just Month 1. But I saw it.
What Week 2 Proved
Friday only worked because Thursday happened.
Thursday I learned bits and bytes for hours. No code. No progress. Pure theory that felt useless at 3:01pm when I wanted to quit.
Friday I manipulated buffers naturally. Built reliability on top of UDP. Created from understanding.
Week 1 taught me I could start. Week 2 taught me what continuing means when life stops accommodating you.
My schedule went from flexible to packed. I didn't reschedule. I showed up at 2pm every day. After five hours of lectures. After calculus and physics and Data Structures.
Showed up tired. Distracted. Half-asleep.
Showed up anyway.
Day 9 was harder than Week 1's Day 4. Not more complex—just exhausted from a packed schedule and theory with no immediate payoff. My eyes physically closing. My mind coming up with logical excuses.
I stayed until 4:30pm.
Most of the time when I think I can't, what I really mean is I don't want to.
Most walls are negotiable.
I understand UDP now. Why connectionless matters. How to implement basic reliability with ACKs. How to manipulate buffers at the byte level.
But there's layers underneath I don't know yet. How the OS constructs packets. Dynamic memory. Complex state. Each layer I learn reveals the next I don't.
That's fine. I'm not becoming an expert in two weeks. I'm becoming someone who can sit with difficulty.
Ten days. Zero missed.
The 3.95 GPA didn't build this server. The guy who refused to leave at 3:01pm did.
Week 3 starts Monday. I'll be there.