AI 资讯
I built Commitea: Git and GitHub explained in Spanish, with an interactive visualizer
When I started programming, Git was hard for me — like anything new is at first. Over time I noticed something: most of the best resources for learning it are in English. And for a lot of people just starting out, that's one more obstacle they shouldn't have to deal with. So in my spare time I built the thing I wish I'd had back then: Commitea . What is it? Two pieces, designed to complement each other: An open source repo with the full documentation in Spanish — from what a commit actually is, to how to get yourself out of trouble with rebase , a cherry-pick , or a push you regret. Every entry follows the same format: the concept in one sentence, a real example with commands, and "how this breaks" (the typical mistake people make). A web app with an interactive visualizer ( commitea-web.vercel.app ) where you type real Git commands and watch, live, what happens to the branch/commit graph. It doesn't touch any real repo — it's an in-memory simulator, but the engine actually replicates real Git behavior: fast-forward vs. merge commit detection, history rewriting on rebase, blocking a branch switch when you have uncommitted changes (just like real Git does), etc. What's in it right now 7 built-in scenarios you can run with one click and watch play out step by step: branch + merge, fast-forward, rebase, cherry-pick + reset --hard, fixing a commit made on the wrong branch, several branches merging in sequence, and stashing changes. Full command support : branch , checkout , commit , merge , rebase , cherry-pick , reset --hard , stash (with an edit helper command to simulate uncommitted changes, since the simulator has no real filesystem), status , and log . Site-wide search (⌘K), powered by Pagefind, indexing only the actual article content — not nav or boilerplate. A feedback widget on every article ("was this helpful?") that stores vote counts in Redis, so I know which content needs work without guessing. Light/dark mode , respecting system preference by default. A ch
AI 资讯
Decided is not done: taking stock before adding more
The first session ended at post 10. The design did not. I came back to it and, before writing a single new decision, asked the least glamorous question a solo project can ask itself: how far along is this, really, and what would it take to call it ready for someone else to review in depth? The answer was more useful than I expected, because it forced a distinction I had been blurring: a settled mechanism is not a hardened design . The fork: promote now, or hold and harden Composition was already reconciled into the binding docs. Coherence had seventeen recorded decisions covering the whole load-bearing core: binding, determinism, precedence, persona content, gender, explainability, detection, activation, the explicit accessor, and a second entity proving the abstraction generalizes. It was tempting to call that reviewable and promote it too. A: promote coherence into the binding docs now. 17 decisions, self-consistent, composition already went. Looks done. B: hold. The mechanism is settled, but the seams between features are not. Harden first, promote second. I took B. The tell was that I could not yet answer a reviewer's most obvious question, "what happens when a composed child is itself a person," without pointing at an open fork. A design you cannot stress at the seams is decided, not done. What "hardened" actually means The value of taking stock was turning a vague "almost there" into a concrete, finite list. Three passes stand between the current state and an in-depth review: 1. Cross-feature interaction pass. Where correctness bugs hide once two features exist. Composition x coherence is done (next post). Uniqueness, null-probability, and locale remain. 2. Surface-enumeration pass. Collect every public member the design has accumulated into one list to accept or cut. Public surface is locked, so this is the gate that matters most. 3. Consistency re-read. Read all the decisions straight through for contradictions and stale cross-references, the kind that creep
AI 资讯
I built topolines, an animated topographic contour background for React
Every couple of projects I ended up rebuilding the same effect: an animated topographic map background, the kind with slowly drifting contour lines. After copy pasting the same WebGL shader for the third time I gave up and turned it into a proper library. It's called topolines . One React component, zero dependencies, everything drawn on the GPU. Repo: https://github.com/idleCyrex/topolines Playground: https://topolines.idlee.xyz/playground How it works The lines are not an image or SVG. A small fragment shader generates a noise field (simplex noise + fbm) and draws contour bands from it, so it animates smoothly at any resolution for basically no CPU cost. The component just manages a canvas and the WebGL state around it. Usage npm i topolines import { Topolines } from " topolines/react " ; export default function Hero () { return < Topolines seed = "hello" color = "#F2EFE6" style = { { position : " fixed " , inset : 0 } } />; } Same seed always renders the same field, so your background is stable between visits. There are props for speed, scale, line width, colors, drift, and an interactive mode where contour rings bloom around the cursor. Things I cared about Zero dependencies, the whole thing is one shader and some glue code SSR safe, works in a Next.js server component tree Pauses when offscreen or when the tab is hidden Respects prefers-reduced-motion (renders one static frame) Clean fallback when WebGL is not available The playground lets you tweak every knob and copy the resulting code out: https://topolines.idlee.xyz/playground It's v0.1 and my first published library, so feedback and feature ideas are very welcome.
AI 资讯
I built Skim: a free open-source Email client for Windows with BYOK AI (MIT)
I built Skim because I tried to find a Windows email client that doesn't suck that hard and couldn't really find one. It's not rocket science to vibecode one, right? Why has nobody done it before? Or is everyone just okay with bloated Outlook or archaic Thunderbird? Skim - free, open-source, MIT-licensed minimalistic offline-first email client with BYOK AI. Quick feature list: Installer under 5 MB Bring Your Own Key to enable AI features: Anthropic/OpenRouter, or any OpenAI-compatible server (including a local one) No menu. Minimalistic and contextual interface - buttons are shown only when you need them Keyboard-first controls: shortcuts for everything, no mouse needed Sweet warm zine design Super modest resource consumption AI features are pretty basic: Cowriter that can scan your recently sent emails, adopt your style, and then write emails and replies that sound like you "Ask this email" - chat with a particular email; it can read attachments and follow links inside it Agentic search across all connected inboxes; the "Ask your inbox" feature can scan your whole inbox One-click summarization and translation A few things I'm actually proud of under the hood The UI part is easy to vibecode. These bits were not. Getting the installer under 5 MB took real work. panic = "abort" alone dropped about 6 MB of unwind tables from the binary, that's 23% off the NSIS installer. I ship a single crypto backend (ring, with aws-lc-rs switched off) so I'm not compiling a second, unused crypto library into the thing. I even wrote a tiny Vite plugin that deletes legacy .woff fonts, since WebView2 always uses woff2 anyway. Pretty much every dependency in Cargo.toml carries a comment justifying its feature flags in kilobytes saved: rustls = { version = "0.23" , default-features = false , features = [ "ring" ] } # aws-lc-rs would compile a second, unused crypto library. ~2 MB of dead weight. No Electron, no bundled Chromium. Tauri 2 uses the system WebView2, so it installs per-user wit
AI 资讯
How We Built a 153-Node Interactive Lore Graph for Black Myth: Zhong Kui Using D3.js and Astro
The Challenge Rendering a complex 153-concept-node, 1,200-edge mythic relationship topology for mobile devices without triggering main-thread layout thrashing or heavy client-side JavaScript execution. The Technical Approach Build-Time D3 Force Layout Computation : Pre-computing node coordinates and physics simulation during the Astro static build step. Zero-Runtime SVG Pre-rendering : Outputting the rendered topology as inline SVG with CSS design tokens, preserving 60 FPS scrolling on mobile. Canonical Lore Data Architecture : Structuring 153 canonical concept nodes across Tang Dynasty exorcistic texts ( Nuo rituals) and Black Myth: Zhong Kui motifs. Check out the live interactive relationship map: Black Myth Lore & Concept Map Official website: blackmyth.game
AI 资讯
One video is worth a thousand pictures
Turning entire novels into narrated, lip-synced, motion video — locally, on a single 16GB GPU, with FLUX, Wan2.2, PuLID, MuseTalk, and ComfyUI. There's an old line: a picture is worth a thousand words. I'd extend it — a video is worth a thousand pictures. So I spent the last few months testing that idea the hard way: I built a pipeline that turns an entire novel into a narrated, lip-synced, motion video. Feed it Pride and Prejudice , or a 400-year-old tale from Strange Tales from a Chinese Studio (聊斋志异), and out comes a finished film with consistent character faces across a hundred-plus scenes. One person. One RTX 4060Ti with 16GB of VRAM. Everything local, no cloud inference. I called it iTube. And honestly — the videos came out better than I expected. Watching a novel you know become a moving, voiced, paced thing is a genuinely different experience from reading a summary of it. That's the bet: that video is a better medium for conveying a story than text is, and the finished clips have mostly convinced me the bet was right. See for yourself before reading another word about how it works: 🎬 Pride and Prejudice — a Western public-domain classic 🎬 聊斋志异 / Strange Tales from a Chinese Studio — a playlist of classical Chinese tales But this post isn't a demo reel. It's about the part nobody warns you about — the part between the models — because that's where the real work turned out to be. The models are instruments, not magic boxes Here's the single most important thing I learned, and the thing I'd want any collaborator to understand before touching a pipeline like this: Each AI package can do exactly one thing well, and your entire job is knowing precisely where each one's ability ends — then writing your script logic to route around the gaps. The stack is not exotic. Most people in generative media know these pieces: FLUX generates the still image for a scene. That's all it does — a single frame. Beautiful, controllable with the right prompt, but frozen. Wan2.2 takes
AI 资讯
I built a browser-based pixel-art & animation editor with Vue, Laravel and AI
I'm a solo dev, and for the past few months I've been building Pixanima — a pixel-art and animation editor that runs entirely in the browser, with an optional AI assistant baked in. It just launched, and I wanted to share the parts that were technically interesting: making a general image model output clean pixel art, an atomic credit system, AI inbetweening for animation, and why the whole business model falls out of one architectural fact. What it is Draw pixel art with layers, groups and effects, animate it on a frame timeline with onion-skin, and export to GIF / sprite sheets / PNG — all client-side, no install. On top of that, an AI assistant turns a text prompt into sprites, seamless tiles and palettes, re-poses characters, and generates in-between animation frames. The frontend is Vue 3 driving an HTML canvas; the backend is Laravel 12 (PHP 8.4) . Here's what I learned. Everything runs in the browser — and that decided the business model The entire editor is client-side. Projects live in IndexedDB ; nothing is uploaded. That's great for privacy and speed, but it has a consequence a lot of people miss: you cannot meaningfully gate a client-side feature. If drawing, layers and export all run in the user's browser, any "pro" paywall around them is both unenforceable and, honestly, hostile to a price-sensitive hobbyist community. So I flipped it: the editor is 100% free, forever . The only paid thing is AI — because AI is the only part with a real marginal cost, and it requires a backend (which conveniently also protects the code that costs money to run). More on that below. Making a general model output clean pixel art The naive approach — prompt a diffusion model with "pixel art, 16 colors" — gives you pixel-art-ish mush: anti-aliased edges, hundreds of colors, no real grid. Useless as an actual sprite. The fix is a post-processing pipeline. The model just produces raw input; the "pixel art" is made deterministically afterward with PHP's GD: 1. Generate a norma
AI 资讯
I built a serverless URL shortener for $4.68/year (total)
I wanted two things: short links under my own brand (every link I share points traffic back to my site ), and a real excuse to run a complete system on the edge — DNS, distributed compute, storage, auth and a dashboard — in production, at zero infrastructure cost. The result is flino.link : a shortener that responds in under 10 ms from 300+ locations, runs entirely on Cloudflare's free tier, and whose only expense is the domain: $4.68 a year. This post covers the design decisions, which is where the interesting parts are. The architecture in 30 seconds A single Cloudflare Worker serves the whole domain: GET /<slug> — the hot path. One read from Workers KV (globally replicated) and a 302 redirect. Nothing else touches that path. /api/links — a REST API with Bearer auth to create, list and delete links. /admin — a single-page dashboard served as inline HTML from the Worker itself. No framework, no build step. A Durable Object with embedded SQLite keeps per-slug click counts. No servers, no containers, no database to manage. The whole Worker is three TypeScript files and zero runtime dependencies. Why a dedicated domain? My first idea was to hang the shortener off a route on flino.dev . Bad idea: shorteners attract abuse — spam, phishing — and their domains sooner or later end up on blocklists. If that happens, I don't want it dragging my main domain down with it. A separate domain isolates that reputation risk completely, and a short .link costs less than a coffee per year. KV for links, a Durable Object for counters This is the central design decision. Workers KV is perfect for a shortener's access pattern — read-heavy, write-light, reads served from the edge — but its writes are eventually consistent : two concurrent increments in different datacenters would clobber each other. For counting clicks, it's useless. A Durable Object solves exactly that: it's a single global instance with transactional SQLite storage. Every increment, no matter which datacenter it comes
AI 资讯
MergeForge: Resolve Git Conflicts in VS Code or Cursor Like in JetBrains
Tired of squinting at VS Code’s stacked merge editor? MergeForge brings a JetBrains-style three-pane conflict resolver to VS Code and Cursor — and pairs it with an AI assistant that actually reads your repository before it suggests a fix. The problem We’ve all been there. You’re halfway through a rebase. Git stops. Twelve files are conflicted. You open one in VS Code… and get that familiar stacked layout: Incoming, Current, and a result pane that somehow still feels like a puzzle with half the pieces missing. If you ever used WebStorm or IntelliJ, you know how good merge tools can feel: Your side on the left Their side on the right The result in the middle Gutter arrows that just… work In VS Code land, that flow never quite arrived. You click Accept Current, Accept Incoming, Accept Both, and hope nothing important got flattened. Word-level diffs? Authorship? A clear “who wrote this chunk?” signal? Often missing when you need them most. And when AI entered the chat, a lot of tools treated conflicts like isolated text blobs: “Here are the <<<<<<< markers. Good luck.” But real merges need context. What was the branch trying to do? What does the surrounding file look like? Who touched this last? Without that, “AI resolve” is just confident guessing. I wanted the JetBrains merge experience — inside VS Code and Cursor — with an assistant that behaves more like a careful teammate than a slot machine. So I built it. The solution: MergeForge MergeForge is an open-source VS Code / Cursor extension that turns conflicted files into a proper three-pane visual merge. Layout: Left Center Right Yours (local) Result (editable, seeded from the merge base) Theirs (incoming) Panes scroll together. Chunks connect with bands. Gutter controls let you accept, ignore, or blend sides without fighting the UI. When you’re done, Apply writes the result and stages it with git. If you prefer Cursor, you’re covered too. The editor works the same; for AI features you plug in your own provider key (
AI 资讯
I Built a CLI to Use Free Web-Based AI Chatbots for Real Development Work — No API Keys, No Extensions
I wanted to use web-based AI chatbots — Claude, Gemini, ChatGPT, Qwen — for actual development work, not just Q&A. The free tiers are generous, and I didn't want to be locked into a single coding agent or pay for API access just to get an assistant to touch my code. But the moment you try to actually use a web chat for real dev work, you hit the same wall every time: you either paste in your whole codebase manually every session, or you give up and reach for a paid extension with an API key behind it. So I built AI Bridge — a CLI tool that bridges a local codebase and any browser-based AI chatbot. No API keys, no extensions running in the background, no vendor lock-in. You pack your code, paste it into whichever AI chat you're using, and apply the changes back with a command. Why not just use Copilot, Cursor, or an API key? Coding agent apps and API-based tools work, but they come with tradeoffs I wanted to avoid: Web-based AI chat plans are usually more generous on the free tier than API usage I'm not locked into one provider — I can switch models mid-project depending on which one is handling a task better There's no background agent or extension — it's just a CLI and whatever chat tab I already have open The tradeoff is that browser chats don't have direct filesystem access. AI Bridge closes that gap without turning it into full manual copy-pasting. How it works There are two modes, depending on project size. Simple Mode is for projects small enough to fit in a single prompt. You pack the codebase, upload it along with a couple of prompt templates, and apply the AI's response back to your files: dotnet tool install --global Tools.AIBridge cd /path/to/your-project ai-bridge init ai-bridge pack # Upload ai-bridge/1-SimpleMode/*.md + the generated context files to your AI # Copy the AI's response, then: ai-bridge apply --paste Advanced Mode is for larger codebases, where uploading everything every time burns tokens and adds noise. Instead, you generate a one-time in
AI 资讯
I turned my phone into a remote deck for my Windows laptop — no cloud, no accounts, one npm start
It started with the dumbest problem in computing: I'm in bed, a movie is playing on my laptop across the room, and pausing it requires physically getting up . Every existing fix annoyed me in some way. Remote desktop apps are overkill and route through someone's cloud. Remote-control apps want accounts, subscriptions, or a native app install. I just wanted my phone to poke my laptop over my own Wi-Fi. So I built LapDeck : one Node.js process on the laptop, a PWA on the phone. Scan a QR code once and your phone becomes an app launcher, touchpad, keyboard, live screen viewer, and media/power remote. MIT licensed, plain JavaScript, no build step. This post is about the four problems that turned out to be more interesting than I expected. The architecture in one line Phone (PWA) ── WebSocket + MJPEG over Wi-Fi ──► Node.js agent (Windows) The agent serves the PWA, exposes a WebSocket for commands, and streams the screen as MJPEG. The protocol is deliberately dumb JSON envelopes — no protobuf, no RPC framework — so a native Android client or a CLI script can speak it in an afternoon. Windows-specific glue (volume, brightness, power, capture) is isolated in src/win/ , so a macOS/Linux port only has to reimplement that layer. Problem 1: mobile keyboards lie to you The obvious way to build a remote keyboard is to listen for keydown and forward key codes. On mobile, this collapses immediately: swipe typing, autocorrect, and IME composition don't emit per-key events. Android will happily tell you every key is keyCode 229 . The fix: stop listening to keys entirely. I keep a hidden input, and on every input event I diff the field's value against the last known state — compute the common prefix, then emit "delete N chars, type this string" to the laptop. Swipe-type a whole word and the laptop receives one clean text insertion. IME composition, autocorrect rewrites, emoji — all just become diffs. The lesson generalizes: on mobile web, treat the text field as the source of truth, n
AI 资讯
SOLID Design Principles: Stop Writing Code That Breaks When You Touch It
Guidelines, not rules. Here's the difference — and why it matters. What is SOLID? SOLID is a set of software design guidelines — not hard rules, but principles that guide how we organize our code. The goal is simple: as your codebase grows and your team scales, things should get easier to change, not harder. SOLID is what makes that possible. Five principles. One goal. Let's walk through each one with real code. S — Single Responsibility Principle A class, function, or method should have one and only one reason to change. The Violation class Bird : def __init__ ( self , name : str , bird_type : str ): self . name = name self . bird_type = bird_type def make_sound ( self ): # two jobs — deciding the type AND making the sound if self . bird_type == " parrot " : print ( " Squawk! " ) elif self . bird_type == " eagle " : print ( " Screech! " ) elif self . bird_type == " owl " : print ( " Hoot! " ) else : print ( " ... " ) make_sound() has two responsibilities — deciding which bird type it is AND making the sound. That's two reasons to change. Add a new bird? Touch make_sound() . Change how sounds work? Touch make_sound() again. Two different reasons, one method. SRP violated. The Fix from abc import ABC , abstractmethod class Bird ( ABC ): def __init__ ( self , name : str ): self . name = name @abstractmethod def make_sound ( self ): pass class Parrot ( Bird ): def make_sound ( self ): print ( " Squawk! " ) class Eagle ( Bird ): def make_sound ( self ): print ( " Screech! " ) class Owl ( Bird ): def make_sound ( self ): print ( " Hoot! " ) # Usage birds = [ Parrot ( " Polly " ), Eagle ( " Sam " ), Owl ( " Oliver " )] for bird in birds : bird . make_sound () Now each class has one responsibility. Parrot.make_sound() only changes if parrots change how they sound. Nothing else touches it. O — Open/Closed Principle A class should be open for extension but closed for modification. SRP and OCP go hand in hand. When you fixed SRP in the Bird example above — you also fixed OCP.
AI 资讯
Next.js 16 on Cloudflare Workers: what broke and what didn't
I shipped a Next.js 16 app on Cloudflare Workers via OpenNext. Not a demo. A real product with streaming chat, server components, D1 at the edge, and anonymous user sessions. Here is what broke, what barely worked, and what turned out to be surprisingly fine. The stack Next.js 16.2 (App Router) @opennextjs/cloudflare 1.19 D1 for SQLite at the edge Streaming chat via the AI binding (DeepSeek-V3 through a Workers proxy) React 19 Tailwind CSS 4 No auth wall, no OAuth, no database on the origin The site runs a few thousand sessions a week across ~30 persona pages, blog posts, guides, and learning content. Most pages are statically generated. The chat interaction is server-rendered components with streaming responses. What worked surprisingly well Static generation and ISR Pages, blogs, guides, persona pages — everything that does not need user-specific rendering — runs as static HTML at deploy time. Next.js 16 with generateStaticParams and fetch caching worked without modification. OpenNext handles the Cloudflare output format. The build step produces something Workers can serve. Revalidations are limited to Workers' cache API, but since most content changes at deploy time, I never hit that limit in production. The one caveat: revalidateTag() does not work the same way in a Workers runtime. Tags are Node.js memory constructs, and Workers are stateless. If you depend on tag-based revalidation for content updates, you need to either trigger deploys or accept stale-while-revalidate behavior from the CDN. D1 at the edge D1 was the least surprising part of the stack. SQL queries from Next.js route handlers feel like calling a regular database. Sessions store in D1, messages store in D1, and the latency is low enough that restoring a full chat thread from 30 messages takes under 200ms cold. The only sharp edge: D1 connections count against your Worker's concurrent request limit in development. With Next.js making its own fetch calls for compilation, I hit the D1 connection ce
AI 资讯
Show DEV: I built a daily web puzzle out of 1-star travel reviews
I built PunFiction: 1-Star Travel Reviews , a free daily web puzzle where you guess world landmarks by deciphering unhinged travel reviews from confused travelers. Tech Stack: Vanilla JS, CSS, HTML, GitHub Pages, MongoDB Atlas The Concept The internet can feel like it's literally overflowing with consumer complaints. I decided to take that negative energy and turn it into a 2-minute daily browser game for your morning coffee break. The Game Loop: Read an absurd 1-star review of a famous world landmark. Decipher the rhyming pun clues to guess the destination. Solving the puzzle unlocks an illustrated cartoon postcard and a sassy reply from the landmark 'manager'. The Tech Stack I wanted PunFiction to feel lightweight and lightning fast. Vanilla JavaScript: No React, Vue, or Svelte. Pure DOM manipulation and client-side logic. Zero Dependencies: No npm install spiral, no build-step headaches, and zero third-party scripts. No Accounts: Daily state, win streaks, and game progress live in localStorage. MongoDB Atlas: Light backend for aggregate puzzle stats (success rates, guess counts, no PII stored). Hosted on GitHub Pages: Static asset delivery via CDN. Give It a Spin If you like wordplay, geography, or just laughing at terrible tourist complaints, give today's daily puzzle a shot: 👉 Play PunFiction: 1-Star Travel Reviews I’d love to hear your thoughts on the UX, the game feel, or your take on building lightweight web games. Drop your feedback (or your worst pun) in the comments!
AI 资讯
I Built the First Collaborative Multi-Persona Sandbox (Because I'm Sick of Cloud Wrappers)
Most AI “apps” these days aren’t really apps. They’re wrappers. A thin UI. A subscription. A cloud call. A monthly fee. And your data quietly piped off to a server farm you’ll never see. I didn’t want to build another one of those. I didn’t want to use another one of those. So, I built something different. I built Bob’s Bar — the first Collaborative Multi-Persona Sandbox (CMPS). Let's be honest, every AI chat feels the same. You ask a question, it answers, repeat. Useful? Yes. Alive? No. I kept thinking: “Why does every AI tool assume I want a one-on-one conversation? Why can’t multiple AIs talk to each other while I watch?” That question became the seed. I wanted a space where multiple personas could exist together, talk to me and each other, and run entirely on my own hardware. I’m an indie dev. I don’t have a server farm, and I don’t want to pay AWS just to host my own brainstorming sessions. So the architecture is 100% local-first: -Engine: Ollama (raw LLM inference) -UI: Python + Gradio (Blocks API for stateful UI) -Distribution: PyInstaller → standalone .exe -Licensing: Lemon Squeezy API (so I could actually sell the damn thing) No cloud. No subscriptions. No data scraping. Just your machine doing the work. But getting four local models to talk to each other without hallucinating is absolute chaos. At first, they spoke twice in a row. They impersonated each other. They put words in the user’s mouth. They derailed into movie scripts. Vane pitched a heist film, and Bob started giving stage directions like “I polish a glass and chuckle.” I had to build what I now call The Bouncer — a regex-powered clean_reply() function that physically chops off AI responses the moment they write a script, impersonate another persona, use bullet points, or hijack the conversation. I also added a seen_in_banter set to prevent any persona from dominating the room. Once the routing was locked down, the magic happened. Because the AIs share a context window, emergent behaviour happen
AI 资讯
How 97.7% of Palworld breeding recipes silently changed in 1.0 — and how to find what yours became
You followed an old breeding guide. You put Penking + Bushi into your breeding farm, dropped the cake, waited for the egg... and out hatched Sibelyx , not the Anubis the guide promised. You're not alone. Your guide isn't broken. The recipe changed. When Palworld hit 1.0, the breeding table got quietly rewritten. Almost every pairing that players had memorized from early-access now produces a different Pal. There's no in-game notice, no patch note that lists the hundreds of changed combos — just a lot of confused hatchings. So I dug into the data. Here's what I found, and the small tool I built to make sense of it. What actually changed in 1.0 I compared two snapshots of the game's breeding data — the pre-1.0 set and the current 1.0 release — both sourced from the open-source PalCalc project. The headline number: 97.7% of comparable pre-1.0 parent pairs now produce a different Pal. That's not a typo. If you take the breeding pairs that existed before 1.0 and run them against the current data, nearly all of them hatch something new. A few concrete examples players keep running into: Old recipe (pre-1.0) What it makes now (1.0) Penking + Bushi Anubis → Sibelyx ... (more pairs in the tool) The mismatch matters because most breeding guides and calculators on the internet still show the old results. Players follow them, breed, and get confused. The subtle trap: renumbering vs. real change There's a detail that trips up every breeding tool that tries to track this. When Palworld 1.0 launched, it also renumbered parts of the Paldeck (Pal #139 vs #116, etc.). A naive diff tool would see the number change and wrongly report "the breeding result changed!" — when really only the number changed, not the actual Pal. To avoid that false signal, I match Pals by their internal game name , not their Paldeck number. A renumbering is not mistaken for a changed breeding result. Only genuine recipe changes are counted. The tool: PalShift I wanted a dead-simple way to answer one question:
AI 资讯
How MV3 Service Workers Made Me Use an Offscreen Document Just to Play a Goat Sound
So I built a Chrome extension that does one very stupid thing: it waits a random amount of time, then screams at you like a goat if you don't dismiss the notification fast enough. Simple idea. Should've been a simple build. It was not, because Manifest V3 said no. The plan was easy, in my head Here's what I thought I needed: chrome.alarms to fire at a random interval chrome.notifications to show a "you good?" popup If the user ignores it for 60 seconds, play a goat sound Step 3 is where things fell apart. Because in Manifest V3, your background script isn't a persistent background page anymore — it's a service worker. And service workers have the audio capabilities of a rock. No Audio() object. No Web Audio API. Nothing. You can't just do new Audio('goat.mp3').play() and call it a day, because there's no DOM for it to live in. I found this out the way everyone finds out things in MV3: by writing the obvious code, watching it silently fail, and then spending 20 minutes wondering if I'd misspelled "goat." Enter: the offscreen document Chrome's answer to "service workers can't do X" for a bunch of X's (audio playback included) is the offscreen document API . It's exactly what it sounds like — a hidden HTML page that exists purely so your extension has something with a DOM, so it can do DOM things. In my case, playing an mp3 of a goat losing its mind. The flow ends up looking like this: service worker (background.js) → creates an offscreen document if one doesn't exist → sends it a message: "play the sound" offscreen.html/offscreen.js → has an <audio> tag → actually plays the sound → closes itself when done It's a little bit like hiring a stunt double because the main actor (your service worker) isn't allowed near water. The offscreen document does the wet work, then goes home. Rough version of what that looks like in code: // background.js async function playGoatSound () { if ( ! ( await chrome . offscreen . hasDocument ())) { await chrome . offscreen . createDocument
AI 资讯
Nexus Engine: One command to Set Up a Complete production Environment
I’m 14 and I got tired of spending hours (sometimes days) setting up new machines. Different distros, different package managers, fragile shell scripts, no rollback. So I built Nexus — a cross-platform environment provisioning engine. One command turns a fresh OS into a fully productive development machine. The Problem Setting up a dev machine is painful: Hundreds of Linux distros with different package managers (apt, pacman, dnf, apk). Shell scripts break easily with no rollback or state management. Tools like Ansible are overkill for laptops. Docker doesn’t configure your host. Dotfile managers don’t install dependencies. Result: Developers lose dozens of hours per year on setup issues. What Nexus Does One static Go binary. Detects your OS, chooses the right package manager, applies declarative YAML profiles, and handles everything with security gates and rollback. No scripts. No manual steps. Works on Linux and Windows (with WSL2 support). Standout Features Cross-distro support — apt, pacman, dnf, apk behind one interface. 7-step orchestrator with rollback — PreFlight → Refresh → Execute → Verify → Audit. Failed foundation packages trigger full rollback. Security gate (SanitizeAndExecute) — Allowlist, metacharacter rejection, timeouts. No raw shell execution. 10 built-in profiles — Go dev, Rust dev, Frontend, Data Science, Ethical Hacking, etc. WSL2 setup in ~60 seconds on Windows. Dotfiles + age-encrypted vault + Distrobox containers . Community profile registry . Optional Tauri GUI dashboard. Architecture Nexus is organized in bounded contexts: BRAIN — Cobra CLI + core engine (Go) DNA — YAML profiles with JSON Schema + struct validation + SHA256 integrity BRIDGE — WSL2 handling (cross-compiled) CONTAINER — Distrobox management VAULT — age encryption REGISTRY — Community profiles Every command goes through a strict security gate. State is crash-safe with atomic writes and append-only logs. Quick Start # Install go install github.com/Sumama-Jameel/nexus-engine/cm
AI 资讯
I built 118+ device tests that run entirely in your browser — no server, no uploads
Every time I needed to check whether my microphone actually worked before a call, or whether a key on a used keyboard was dead, I ended up on some sketchy "free online tester" that wanted an account, showed six ad banners, and — the worst part — happily streamed my webcam to a server I knew nothing about. So I built the thing I actually wanted: TestOnDevice — 118+ device tests that run 100% in the browser. No installs, no account, and nothing you record ever leaves your machine. Here's what I learned building it. The core constraint: the network is off-limits The single rule that shaped the whole project: no device data touches a server. No webcam frames, no audio buffers, no keystrokes, no sensor readings. That constraint turned out to be freeing rather than limiting, because modern browser APIs are genuinely powerful. Almost every "device test" is just a Web API plus a bit of rendering: What you're testing The API doing the work Microphone / speakers MediaDevices.getUserMedia , Web Audio ( AnalyserNode ) Webcam getUserMedia , <video> , MediaStreamTrack.getSettings() Keyboard keydown / keyup , KeyboardEvent.code Mouse / touch / stylus Pointer Events, PointerEvent.pressure Gamepads Gamepad API MIDI keyboards Web MIDI API Display ( dead pixels , refresh rate ) Fullscreen + requestAnimationFrame Motion / orientation DeviceOrientationEvent , DeviceMotionEvent A live mic meter, entirely local The microphone test is a good example of how little you need. Grab a stream, wire it into an AnalyserNode , and compute RMS on each frame for a level meter — no recording, no upload: const stream = await navigator . mediaDevices . getUserMedia ({ audio : true }); const ctx = new AudioContext (); const analyser = ctx . createAnalyser (); ctx . createMediaStreamSource ( stream ). connect ( analyser ); const data = new Uint8Array ( analyser . frequencyBinCount ); function tick () { analyser . getByteTimeDomainData ( data ); let sum = 0 ; for ( const v of data ) { const x = ( v - 128 )
AI 资讯
I built a vector topographic contour map generator for designers (SVG export)
Hey everyone! 👋 As a designer, I constantly needed high-quality vector topographic contour lines and generative patterns for branding, UI hero backgrounds, and print projects. Most existing tools were either heavy GIS software (like QGIS) or required static file purchases. So I built Topolines —a fast, web-based vector topographic generator. 🎛️ Key Features: Parametric Control: Fine-tune elevation density, noise scale, detail, and line weights in real-time. Custom Styling: Full visual control over color palettes, gradients, contrast, and backgrounds. Clean Vector Export: Instant SVG exports (perfect for Figma, Illustrator, or web code) and HD PNGs. Frictionless Free Tier: Direct PNG exports without even needing an account. I'd love for you to try it out at topolines.app and let me know your feedback or feature requests!