3161 words
16 minutes
2025 Recap: The Craziest Year of My Life

The year in about two and a half minutes. The background illustrations in the animation and this post are AI-generated (Codex), with the chibi main character as me; the white-framed images in the animation are real photos and screenshots; the narration is an AI voice (Gemini TTS).

Some background first: before 2025, I could barely code. All I had built was a small Pygame game and, in the first semester of sophomore year, my first LINE Bot connected to an LLM; that was also when I first touched GitHub, and I still didn’t really know how to use it.

This post is about how someone like that, within one year, got to the point of making a 30 kg robot dog build its own map and walk on its own.

In December, I wrote a sentence in my journal:

My growth in the first half of the year and in the second half, after the internship, are on completely different levels. It felt like five times the speed.

I stopped for a moment after writing it. In early 2025 I was following online tutorials to build small React projects; by the end of the year, I was using code to make a 30 kg robot dog stand up, sit down and walk on its own in my living room. So much happened in between that it still feels unreal when I look back.

The biggest thing this year taught me: you never suddenly get stronger; it accumulates step by step. While it is happening, you can’t tell how far you have come. Only when you look back six months or a year later do you realize you are somewhere you never imagined.

So this post is that look back.

Bar chart of monthly GitHub contributions in 2025: 223 in January, 308 in March, a low of 38 in June, then rising from 75 in July to 471 in December; 2,215 for the year versus 73 in 2024

My GitHub contributions: 73 in all of 2024, 2,215 in 2025 (about half from private repos).

Put the me from the start of the year next to the me from the end of it, and the difference looks roughly like this:

Start of 2025End of 2025
What I had builtOne small Pygame game, one LINE Bot, plus snake from a tutorialEvery feature I owned at my internship shipped, plus an AI debate platform
GitHub73 contributions in all of 2024; had just learned to use it2,215 contributions in 2025; my first repo past ten stars
BackendHadn’t touched much backend or APIsBuilt my own APIs, split into Repository, Service and Types layers
RoboticsNo robotics development experience at allMade a robot dog stand up, build a map and navigate on its own on ROS 2

The starting point: before 2025, I could barely code#

First, where I started.

Before 2024, I was a complete beginner. My only experience was taking Python class a bit more seriously than others and building a Chrome-dinosaur-style game in Pygame. In the second semester of freshman year, a web class introduced me to HTML and CSS; my first website had a Frieren GIF as its background, which makes me laugh now. But that is when I started to feel that programming is basically magic: it lets you build cool things that were impossible before.

In the first semester of sophomore year, I touched GitHub for the first time, but I still didn’t really know how to use it. That same semester, I built my first LINE Bot connected to an LLM, connected a database for the first time with PHP, and suffered through my first deployments on Cloud Run. Back then, I had no idea what I would be doing a year later.

January to March: from winter self-study to my first RAG#

AI-generated illustration: late on a winter night, a student codes at a desk with a laptop, a stack of programming books and a hot drink, snow outside

Over winter break I decided to learn React properly and wrote myself a study plan:

  1. Build solid JavaScript and responsive-design basics.
  2. Follow tutorials to build small React projects: snake, tic-tac-toe, a memory card game, and start to understand what a “component” is.
  3. Try TypeScript for the first time: types felt like a hassle at first, and then I was hooked.
  4. Start buying programming books, a habit I still have.

In February I started SoulNet, my first complete React project: a social platform built with React, Firebase and Cloudflare R2. It took me from “can write React” to “can build a complete product with React”.

In March, for Systems Analysis and Design, we built EchoMind: an AI study assistant for Fu Jen’s information management students. We turned course experience from 42 courses and the department’s rules into a knowledge base, and used RAG to retrieve before the model answered. It was the first LLM application I built end to end, and the first time I really felt what LLMs could do. March was also my busiest month on GitHub in the first half of the year.

Also in March, I happened to see big companies hiring interns, and learned for the first time that students like me could apply too. On my first try, I applied to just two.

April to June: wrapping up, then my first offer#

April and May were mostly about finishing the semester’s projects.

In June I got a frontend internship offer from a startup. The skills it asked for, React, TypeScript and Firebase, were exactly what I had practiced one by one over the past six months. Only then did I realize that the ordinary-looking winter study plan had been paving the way for this all along.

To be honest, I was a bit burned out in June; my GitHub contributions hit the year’s low of 38. But it was right after that low point that the second half of the year took off.

July to December: my first internship#

AI-generated illustration: a student at an office desk with two monitors showing a simplified step-by-step flow, sticky notes on the screen

I started in early July. My title was frontend, but in practice I handled screens, APIs, the database and Cloud Functions, closer to full stack. Interns followed the same process as full-time engineers: confirm the spec, build, verify on staging, code review, ship, demo. Every feature I owned shipped.

In late July I also started keeping a daily journal in Obsidian. It may be the best decision I made all year; many details in this post come from those entries.

Week one: starting with a small badge#

My first task was small: adding a social-account verification badge to creator pages. Along with it I learned event tracking, recording what users do on the site so the product team can judge whether a change worked. Small task, but it was the first time I changed a product that real people were using.

Onboarding: from 7 steps to 5#

At the end of July I got my first big ticket: cut the new-user onboarding flow from 7 steps to 5.

It was more complicated than it looked. Two versions of the old code existed side by side, a previous refactor had been left half-done, and the logic for three ways to create a profile page (build it yourself, generate it with AI, import from an external link) was scattered everywhere.

My approach was to dig first, then build. I went through the old code file by file to see what was still used and what was dead, then pulled the three flows into one controlling component with centralized form state. The existing progress-bar component would not fit into the old code, so I wrote a lightweight one myself. The redesign covered creator-type selection (swipeable on mobile), template selection, profile and social links, a completion page, Chinese and English, and event tracking.

The core took 4 days; from ticket to launch took about three weeks.

Those days were actually painful. I wrote in my journal: this ticket has been stuck way too long, four days now, and I’m feeling some deadline pressure; the next day I wrote: CSS is driving me crazy. When I had just passed one month at the internship, what I wrote was: it honestly feels like two or three months.

What I learned:

  • When you inherit an old system, spending more time reading code than writing it is normal.
  • To fix CSS, find the parent first, strip the extra widths and spacing, then rebuild with flex.
  • Most important was the mindset: I went from “let AI write it for me” to “understand the code first, then use AI to go faster”.

AI suspicious-account review: putting AI into a real product#

In August the platform was hit by a wave of scam accounts, and manual review and keyword blocking couldn’t keep up.

I built the first version: n8n scraped the text of new account pages, an LLM judged it, and the result went back into the admin review queue. I logged the results of every prompt version and compared them on more than 150 test cases; version 3 did best.

Then scammers started hiding content in images and external links, which text alone could not catch. A senior engineer rebuilt the judging flow with LangGraph, adding image analysis and link screenshots; I connected the new results back into the admin tools, with category lists, block/unblock and batch actions. Because the two sides were connected through a fixed data format from the start, switching to version 2 needed almost no changes on my side.

This was the first time I understood that smoothing the workflow between people and AI often matters more than squeezing out model accuracy.

Product reviews: my first backend#

Product reviews, which I started in late September, was my first job building my own API: creators could show product reviews on their pages, and pin, feature and search them.

Before this, I had written almost no backend. In mid-September I was still complaining in my journal that my tickets were “way more than I expected, mainly because I haven’t touched much backend or APIs”; two weeks later, I wrote: today I did my first full-stack ticket, including opening my own API and connecting the frontend and the admin side.

At first I put all the logic in one API. After a senior colleague suggested layering it, I refactored it into Repository, Service and Types layers, and chose the folder naming myself. I started testing APIs with Postman; Firestore needed composite indexes for multi-field filtering with sorting, and I was stuck on those rules for almost a month.

Another trap was when to write data: at first, every form change was written straight to the database; later it became a draft that was only written when you pressed save. It taught me to separate “what’s on screen”, “unsaved changes” and “the real data”. The feature passed its demo in late October.

How I changed#

Looking back on those six months, the biggest change was not a framework I learned, but:

  • From making it work to thinking about architecture: I used to stop at “it runs”; now I think about layers, naming and how easy it will be to change.
  • From depending on AI to steering it: understand first, then let AI speed me up.
  • From writing for myself to writing for a team: code review taught me that code is written for people to read.

At the end of August I wrote in my journal that after getting knocked around by the real world in July and August, I finally understood how precious student-life freedom is. But getting knocked around is also why I grew so fast.

August and September: my first 3D printer, bought with internship pay#

AI-generated illustration: late at night, a student excitedly watches a 3D printer print its first small part

At a capstone meeting at the end of August, we decided to extend the project toward Arduino and 3D printing. The next day, I bought my first 3D printer with my summer internship pay.

It arrived in early September; I assembled it with friends and printed a few small tools and my first model. Around then I wrote a sentence that became the direction for my whole second half of the year: don’t limit yourself to frontend; become an engineer who can do both software and hardware.

September to December: choosing a robot dog#

Only two options from the department#

In September we had to pick a capstone topic. The department initially offered only two options, which felt limiting, so I compared every platform I could think of:

OptionDevelopment accessVerdict
Ray-Ban Meta glassesNo open SDK; only indirect access through a phoneToo limited
Kebbi Air robotSDK available (Android/Unity)First-phase pick
Rokid AR glassesNo front cameraCan’t sense the real world

What I wrote at the time was: treat the robot as “a medium for sensors and actions”, and let a computer do the thinking. That turned out to be the seed of the whole later architecture.

At the end of September, I pitched a bold combination at a meeting: Kebbi, a Go2 robot dog, and 3D printing. In early October I talked with my professor for three hours, and he agreed to help us borrow a Go2. At a vendor meeting in mid-October, it became clear that instead of speculating, we should borrow the dog and test it as soon as possible.

Late October: a 30 kg robot dog#

AI-generated illustration: a student struggles to carry a huge cardboard box out of a university building, a white robot dog peeking out

In late October the topic was set, and we went to pick up the robot dog. My journal entry that day said only: so heavy, 30 kg.

But what was really heavy wasn’t the dog; it was that at the time I had no robotics development experience at all. That same week, I was reading my operating systems textbook and working on internship tickets during the day, then teaching myself ROS 2 and Isaac Sim at night.

Photo: the Go2 robot dog just after we borrowed it, still in its original foam case

Photo: the Go2, freshly borrowed, still lying in its original case.

We had borrowed a Go2 Pro, which can’t use the official education-edition development workflow, so I built ROS 2 on WSL2 and connected over WebRTC with the open-source go2_ros2_sdk. By the end of the month, Isaac Sim and the SDK both compiled, but launching failed on a Nav2 error.

November: making it stand for the first time#

AI-generated illustration: in a small living room at night, a white robot dog stands up for the first time while a student cheers in front of a laptop

In early November, the simulated Go2 moved for the first time. A few days later, I used the SDK to make the real robot dog stand up and sit down. Then I was stuck for days: it simply would not move on command, until I found that balance mode was off. Once it was on, I could finally drive it from my computer.

During this stretch I wrote in my journal that robot dog development was completely outside my field, and I felt a little anxious about whether I could actually pull it off. Just connecting my Mac to the Go2 took more than two hours; one day I debugged all night, and what I wrote at the end was: debug, write code, debug again, an endless loop, and you get stronger along the way.

The capstone topic also changed several times along the way: from emotional companionship without navigation, to “smart object finding” with navigation back in.

November to December: navigation, one roadblock after another#

Navigation was the hardest part of the second half:

  • SLAM worked: the dog could finally map the living room.
  • Nav2 moved the dog on its own for the first time: but Wi-Fi latency was about 700 ms with dropped packets, so it braked too late and bumped a wall.
  • Rewiring the network: the dual-NIC problem alone took three days, and I wrote in my journal “this is really hard”. After setting up a dual bridged network, Windows, a Mac virtual machine and the Go2 could finally reach each other.
  • Three hours on one error: it turned out to be a cached ROS 2 background daemon.
  • First autonomous avoidance: but the vision-only approach succeeded only about 50 to 60 percent of the time.
  • By year’s end, the semantic object-finding MVP was done.

In mid-December, I finally wrote in my journal: today I officially walked out of the painful build phase of the past month, and development is going more and more smoothly.

In late November I wrote that every day of development brought new problems, but I could feel myself growing faster. Another day I wrote: exhausting, but pretty fun too, in a masochistic way.

Around the same time I built my Web Programming final project, DebateAI: two AIs debating the same topic, which was also my way of learning LangGraph. One day I worked on DebateAI in the afternoon and the robot dog at night, and my journal said: so tired.

Year’s end: my first repo past ten stars#

At the end of December, the capstone repo got its 11th star. My journal said: only two of them are people I know.

Eleven stars is not much, but it was the first time I felt that strangers found something I built useful.

Closing#

Looking back at 2025:

  • In 2024, I had only 73 GitHub contributions all year, and still didn’t really know how to use GitHub.
  • In January, I was following tutorials to build snake.
  • In June, I got my first internship.
  • In August, I rebuilt a sign-up flow real people were using, and bought my first 3D printer.
  • In November, I made a robot dog stand up for the first time.
  • In December, I wrote that the two halves of my year were on completely different levels.

In the last journal entry of the year, I described it like this: the year that changed my life, and also the year I worked hardest and was most disciplined.

Each step looked ordinary at the time, but put together, they make the craziest year of my life so far.

There is one line from my original recap draft I want to end with: when you are ready, with courage and the ability to learn, you can become anyone.

In 2026, this robot dog would take me much further: first place at the capstone presentations, a demo at National Taiwan University, and my own robot arms and robots. That is a story for another post. For me this is a marathon, and in 2025 I had just finished the first kilometer.

2025 Recap: The Craziest Year of My Life
https://blog.roy422.dev/en/blog/2025-review/
Author
Roy Lu
Published at
2026-01-20
License
CC BY-NC-SA 4.0