exogen

Joined 19 years ago

Karma
3,377
Submissions
522
Member since
Mar 7
JavaScript, Python, and general web hacker.

Web: https://brianbeck.com/

Mastodon: https://hachyderm.io/@exogen

View on Hacker News

Recent submissions

Comment · 4 months ago
Odd, I wonder if it has to do with modern macOS resolution scaling (how there basically is no "native physical resolution" setting anymore). i.e. maybe up to a certain point it's also simply scaling the hardware-rendered cursor, if that's even possible?
Comment · 4 months ago
Comment · 4 months ago
Before reading the background info, I was going to recommend a much simpler fix, but they actually already mention it in there: "Also the mouse cursor size can be changed."

This was going to be my suggestion because it also fixed a similar CPU/GPU related issue many years ago: Apple's own TV.app would have minuscule color handling differences whenever subtitles would show during a movie. This was driving me nuts while showing a moody black & white film for a movie night - every time a subtitle would pop up, the entire scene's black levels would shift slightly (and it wasn't any kind of adaptive/localized brightness or anything like that, it was the actual rendering).

Some online sleuthing revealed it was GPU related (pure GPU video decoding vs. the CPU overlaying subtitles on the screen), and that bumping up the cursor size (even the tiniest amount) in mouse settings would fix it. It worked.

It's barely noticeable, but I actually prefer the slightly bigger mouse cursor now anyway, so it's part of my standard macOS setup.

Comment · 6 months ago
I am sorry that you are bad at analogies.
Comment · 6 months ago
Because that third-party code adds its own HTML tags.

Because that third-party code adds its own CSS.

Because my HTML and the third-party HTML live in the same document. Thus, my CSS could target their HTML, and their CSS could target my HTML. There are no modules and therefore no module boundaries.

Because my CSS and the third-party CSS share a global namespace. Thus, their CSS selectors might overlap with my CSS selectors. Hopefully nobody called anything ".container" or ".wrapper" or ".button" since there's no namespacing, right?

Keep in mind these components might be arbitrarily nestable. Maybe my elements can be a child of theirs? Maybe theirs can be a child of mine? Can I opt out of the cascade? Should I?

Maybe we could all use the Shadow DOM? I don't really have control over what third-parties do, but let's say I dig into their implementation (what fun) and choose only ones that use the Shadow DOM. Now I've massively bumped up the complexity and ensured my document can't render without JavaScript; lots of user-agents go right out the window and see nothing.

Let's reduce it to the simplest possible case: you and I are working on the same website, but I'm responsible for the header and you're responsible for the footer. We even have our own separate .css files. Yay, no merge conflicts.

Can you and I safely write our selectors without coordinating with each other?

(If you think the answer is yes... you're wrong.)

Now add a few dozen more team members and several third-parties who we in fact CANNOT coordinate with.

Everywhere you turn there are tradeoffs and half-solutions. Turns out "Just Do X" is not very helpful. Thus, I don't blame people at all for developing their own solutions to scaling CSS - like OP's framework.

Comment · 6 months ago
Exactly. The problem is the platform has not kept up with the way it's used in practice. Features are added with strange priorities, and obvious blind spots ignored, leading to it being under-developed in many areas, and over-developed in a handful of others. We get vendors working on weird stuff like Web Bluetooth before obvious things like element anchoring (finally, yay... but still just a Working Draft) and reliable element position tracking (still a huge pain).

There are still no affordances for many things, so people have to invent their own solutions.

Comment · 6 months ago
> A selector is not not a variable or a function. CSS has functions (e.g translate) and it has variables, which are both distinct concepts in the language from selectors.

That misses the point. They're identifiers scoped to the entire document - the same way global variables and global functions are identifiers scoped to an entire program.

Comment · 6 months ago
Because many web sites and apps aren't as simple as "my first homepage" and don't only consist of first-party code. Think component libraries. Reusable code. Content management systems. Third-party SDKs (chat widgets, support widgets, payment widgets like Stripe, etc.).

One of my earliest webdev jobs was at a company whose product was a widget you could add to your site by adding our `<script>` tag. Thus, our CSS needed to coexist with the first-party site's, not to mention any other third-party widgets on there. In other words: the same exact reason you need modules in traditional languages.

Comment · 6 months ago
Been writing CSS since 1997. Your mistake is thinking that the authors of these frameworks (or their target audience) just don't know how to use CSS correctly. But it's far more likely that the authors know far, far more about the intricacies of CSS and how it works than most developers. These frameworks are almost always developed by people with deep experience in the trenches, who have realized that CSS scales fucking terribly... not because they are misinformed or did anything wrong.

Namely:

- Selectors are a global namespace. Imagine if every variable and function in your favorite programming languages were global and so had to be unique. No modules or namespaces. Developing a system to fix that would be pretty high on my list of priorities... coming up with a cool solution and then people telling me to "just learn the language" would be pretty fucking infuriating, don't you think?

- Several fighting priority systems (did you know about newer ones like @layer?). And equivalent priority falls back to source order - OK, so how do you square that with dynamic loading? Some navigation paths through an app would inject some CSS first whereas others would inject other CSS first. Good luck!

Comment · 8 months ago
Somewhat familiar with them, but can't say I've ever built anything with them. I'm curious though: are you aware that people already consider React and its cousins to be immediate mode style APIs for the Web? At least, as close as you can reasonably get when your rendering target is the DOM? That's why `UI = f(state)` is so often cited in React literature; components are functions that don't know anything about the "widget tree" or "instances" or anything like that, you always just return the latest output that you want with the data/input you receive, as if you are rendering "from scratch" each time. Components don't really know whether they're "initializing" or "updating" or anything like that, they just know they're "rendering"; React takes care of reconciling that output with the actual DOM.

So, if that's not good enough for you, what would an even more faithful immediate mode API even look like? (And if your idea includes ditching the DOM as the render target, which is inherently "retained mode" and could never be otherwise due to performance and DOM state (like focus), I'm afraid it's a nonstarter.)

Comment · 8 months ago
Comment · 8 months ago
> It is still a string, even if a template string or whatever it is called, no?

No.

> That still leaves the door open for XSS.

The door for that in React is called `dangerouslySetInnerHTML`, but it's extremely rarely used.

> jsx needs to rename HTML attributes, because of overlap with JS keywords like "class"

That's not really inherent to JSX, just React's use of it. SolidJS, for example, uses `class` instead. But in any case – JSX didn't make up those names. Those are the property names on JavaScript's DOM classes. The fact that there's confusion between "attributes" and "properties" is pretty baked-in to the Web platform, even causing confusion in standard Web Components. Every DOM library and framework (even jQuery) has needed to decide whether it's operating on properties or attributes.

    const div = document.createElement('div');
    div.className = 'foo';
> It also comes with hacks like "<>" or fragment.

The DOM has the same concept, DocumentFragment. How else would you represent e.g. "two sibling nodes with no parent node"?

> It lacks the awareness of context and therefore is not truly like HTML.

On the contrary, I'd argue it has way more context. It knows, and will warn you, if you try to do any DOM element nesting that the HTML spec forbids, for example.

> can be structurally pattern matched upon and iterated through, like a proper tree structure.

You are literally describing the output of JSX. Glad you like it ;)

Comment · 8 months ago
I'd give people the benefit of the doubt. Personally, having built UI with Win32, WinForms, VisualBasic, Cocoa/Interface Builder, Qt, Tcl/Tk, XSLT, vanilla HTML/JS, jQuery, Backbone, Ember, Knockout, Bootstrap, MooTools, YUI, ExtJS, Svelte, Web Components, and React (including Preact, SolidJS…)… I'll happily choose the React approach. The only other one I would even describe as "good" was Qt.

I also don't get why "XML-like syntax in the JS code" is even a point worth complaining about. If anything, we should be encouraging people to experiment with more DSLs for building UIs. Make your tools suit the task. Who the fuck cares, if it's clear and productive?

Comment · 9 months ago
It would be possible to have it decode the .dts and .dif formats on demand - that was my original plan - just much less efficient for users, as the .glb files are about 1/5 of the file size on average. (I also assume glTF loading/rendering has had a lot more optimization work put into it than what I'd be able to accomplish.) For these reasons it seemed more productive to have it work on the Blender addons as a starting point rather than JavaScript/TypeScript parsers for the original formats. I still ship the original assets alongside the .glb files (meaning they have URLs just aren't loaded) in case I want to switch it someday.

Some of the custom features you may be referring to I implemented as custom properties in the glTF output - like surface flags. "Outside Visible" is one example, it's a flag baked into each .dif surface that determines whether rays can reach it from the outside, so the engine knows whether to apply the map's directional sunlight, or just ambient and light map lighting. So, even though it technically could try to render with modern PBR, dynamic lighting/shadows and all that, it instead renders as close to the original as possible using the same (or similar) techniques. Comparing screenshots with actual Tribes 2 renders is often indistinguishable unless you really know what to look for!

Comment · 9 months ago
I've been thinking about this topic and am glad to see it come up: AI is going to be a huge boon for digital preservation & restoration projects like this. I realized this while building this project (a map explorer for Tribes 2): https://exogen.github.io/t2-mapper/

Old games like this have a small (and shrinking) audience of people who care about them. With Tribes 2, for example, there are only ~50 people who actively play on a regular basis. A subset of those people are programmers, and a subset of those have the time & energy to put into a project like t2-mapper, assuming they're even interested. I got a basic version working, but then Claude Code helped decode and convert obsolete Dynamix/Torque3D file formats (improving existing Blender addons that were incomplete), got TorqueScript running in the browser, wrote shaders, and generally helped figure out what the original C++ code was doing.

In the past, you'd need the stars to perfectly align for stuff like this to happen: a passionate super-fan with the time, resources, knowledge, and persistence to see it through. Now, you mostly just need the persistence (and maybe a couple hundred bucks for tokens). I foresee people with niche interests (but not necessarily a programmer's skillset) being able to extend the lifetime (and maybe audience) of their obscure or obsolete software.

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton