Friday, July 25, 2025

Thinking about Agile and the Games Industry

 Something I wrote into Teams at work as we're discussing our Agile process:

I was listening to the gaming podcast "Get Played" the other day - very idiosyncratic episode where one of the 3 improv comedian hosts [Nick Wiger] was running it solo. He had some experience doing tech support then QA then some design for Activision (he was on the team for the old Fantastic Four movie tie in game). Anyway, it reminded me of how much the game industry was responsible for popularizing Agile - both the scale of what a AAA title takes, and the process of nightly builds, and constant deliveries. 

 I mean, I'm not sure I love game industry as a model; they are in forever crunch mode and really exploit the fact that so many young smart people will sacrifice so much to be In The Industry. But for those among us who dig big games, it's interesting to think about the tie-in with how Agile structures our working day lives.

Gall's Law

 Gall's Law: A complex system that works is invariably found to have evolved from a simple system that worked.
The corollary is devastating: A complex system designed from scratch never works and cannot be patched up to make it work.
This is why:
- Microservices migrations often fail when done as big-bang rewrites
- New frameworks struggle against battle-tested ones
- "Clean slate" projects often become technical debt faster
Start simple. Add complexity only when the simple system breaks.

Robert Roskam


Thursday, July 24, 2025

final answers for export ReactFlow as PDF and exporting as one step


 I mentioned earlier all the heartache we had trying to export ReactFlow diagrams via KendoPDF (short of it was KendoPDF assumed the visual descriptor information for a SVG would be embedded, not external CSS - see this github issue for Kendo after ReactFlow helped me figure out it wasn't going to be solved as a ReactFlow thing.

After investigating other possible paths (ReactFlow talks about doing server side stuff via Puppeteer, and react-pdf was another package I might have started looking at. (We also considered the caveman approach of just firing the browser print dialog and letting the user save as PDF - but even that had terrible scaling problems and wasn't WYSIWYG)) we combined html-to-image package (which is the official recommendation - but be sure to heed the advice of locking in the version to 1.11.11!) with jsPDF.  (this meant we had to glue the diagram as a PNG rather than a scalable SVG - jsPDF doesn't handle SVG, maybe for reasons related to KendoPDF's not handling it. SVG is a tricky beast to render, historically..)

One gotcha was this... we had a requirement of wrapping the diagram in a standardized title frame for the PDF - but that frame wasn't there during normal use. With KendoPDF we had a rather neat solution: it added a "k-pdf-export" class, and we could use that to show a frame that was usually hidden but would then show up on export.

With the new solution, it wasn't clear when we could add in that class. My first pass was to do a "preview / export  mode" but that wasn't really part of the desired UX... they just wanted the class added on the fly, but that gets tricky with React and DOM rendering cycles. (generating and downloading a snapshot is pretty imperative, so add a class, snapshot, remove class got weird.) 

In short, doing a

    await new Promise(requestAnimationFrame);

after each mutation of the classList for the wrapping object seemed to cover it 

Wednesday, July 23, 2025

hot take

 Way Too Hot Take: TypeScript is the Hungarian Notation of our time. 

Monday, July 21, 2025

commented out code: make a PDF

One of my least favorite lint-ish ideas is that you shouldn't have commented out code, that it's ok to hope future coders know there's useful code to be found in the repository, if they don't mind foraging like hungry raccoons through trash.

BUT, that's the way my work seems to be leaning.

Anyway, some code I am taking out but would like to have handy:

  // const a = document.createElement('a');
  // a.setAttribute('download', 'reactflow.svg');
  // console.log(dataUrl);
  // a.setAttribute('href', dataUrl);
  // a.click();

that's just a handy of making a link to trigger a download, and even after we decided to pass dataUrl to jsPdf, I could see cases where we'd want to download the graphic file directly (for instance, the option to download an SVG, when the PDFs we make can only embed PNGs, which lose the nice formatting.)

Thursday, July 17, 2025

KendoPDF and SVGs that depend on CSS

 I made some progress from the "why won't ReactFlow edges show in KendoPDF exported PDFs" I had the other day, at least in understanding the problem.

I started this thread on the reactflow github that got me digging into - A ok, Kendo DOES do SVGs, right? So what's special about these node lines?

Eventually it got me back to starting this bug report on the Kendo side - along with this crude StackBlitz (I have to remember StackBlitz, it's one of the better CodeSandbox type things I've seen, love being able to tool around in a lil terminal.

My experiments indicate that ReactFlow depends on CSS to do stuff like stroke and strokeWidth inside of PNGs but that gets ignored by the KendoPDF rendering process. 

Bummer! I need to see if html2canvas or html-to-image have better results, maybe combine with jsPdf. 

Tuesday, July 15, 2025

problems with kendopdf and reactflow

 It felt like Kendo-React-PDF might be an easy way of exporting stuff made in ReactFlow but weirdly the edges (lines connecting the nodes) don't show. I started with a minimal bit of hello, world for both to show that it wasn't something else that was causing the lines not to show:

 run it with

npm init vite my-react-flow-app -- --template react

cd my-react-flow-app

npm install @xyflow/react

npm install @progress/kendo-react-pdf

npm run dev


App.jsx:

import { useState, useCallback, useRef } from "react";
import {
  ReactFlow,
  applyNodeChanges,
  applyEdgeChanges,
  addEdge,
} from "@xyflow/react";
import "@xyflow/react/dist/style.css";
import { PDFExport } from "@progress/kendo-react-pdf";
 
const initialNodes = [
  { id: "n1", position: { x: 0, y: 0 }, data: { label: "Node 1" } },
  { id: "n2", position: { x: 0, y: 100 }, data: { label: "Node 2" } },
];
const initialEdges = [{ id: "n1-n2", source: "n1", target: "n2" }];
 
export default function App() {
  const [nodes, setNodes] = useState(initialNodes);
  const [edges, setEdges] = useState(initialEdges);
 
  const pdfExportRef = useRef(null);
 
  const onNodesChange = useCallback(
    (changes) =>
      setNodes((nodesSnapshot) => applyNodeChanges(changes, nodesSnapshot)),
    []
  );
  const onEdgesChange = useCallback(
    (changes) =>
      setEdges((edgesSnapshot) => applyEdgeChanges(changes, edgesSnapshot)),
    []
  );
  const onConnect = useCallback(
    (params) => setEdges((edgesSnapshot) => addEdge(params, edgesSnapshot)),
    []
  );
 
  const exportToPDF = () => {
    if (pdfExportRef.current) {
      pdfExportRef.current.save();
    }
  };
 
  return (
    <div>
      <PDFExport ref={pdfExportRef} fileName={"output.pdf"}>
        <div style={{ width: "100vw", height: "80vh" }}>
          <ReactFlow
            nodes={nodes}
            edges={edges}
            onNodesChange={onNodesChange}
            onEdgesChange={onEdgesChange}
            onConnect={onConnect}
            fitView
          />
        </div>
        <button onClick={exportToPDF}>click me</button>
      </PDFExport>
    </div>
  );

Friday, July 11, 2025

vibe coders know the value of everything and the cost of nothing.

I suspect that a big part of the next phase of dev work in general (like industry wide) is going to be more QA-like. 
 

A gray lining to the silver cloud of AI buddies (from the company and project perspective - obviously they are a threatening as hell frenemy for anyone who develops software for a living) - their code is so verbose. Beside the "tell" of explanatory comments after someone has used AI, some LLMs style favor a more baroque style. (This is anecdotal; it might be possible to direct an AI to be more concise, and maybe different LLMs act differently, this is just some empirical observation.)
 

I already think the industry doesn't put enough emphasis on simplicity and traceability and transparency, and there are places in my work's own code base where I think... this could be/should be more concise, and that enacts a long term cost in terms of maintainability. 


It reminds me of the old line "LISP programmers know the value of everything and the cost of nothing."...  and the old Microsoft vs Unix approach paradigms, where Microsoft would often do so much for you, but when it came time to understand it to fix some low level thing, it was rough going.  

Friday, July 4, 2025

chatGPT to make a simple score keeper

There's a pretty cool, kid-friendly party game called Without Fail - and even though the scoring is pretty simple (if you and your high bid partner complete a challenge, you get a point, if you fail you lost a point and everyone else gains a point) it can be fiddly to keep track of. So I had ChatGPT help me build a simple score tracker for it.

I feel like I'm a little ahead of the curve with my VPS, I can just throw this up and share it. I mean it could work as a static file on any personal site, but when I can just slap up server side stuff as well, I am really empowered with a real synergy with what ChatGPT can help out with.

Tuesday, July 1, 2025

Learning GraphQL

I am looking forward to tackling How to GraphQL.

I am not sure it always pulls its weight complexity wise (it seems like there would be ways to tell a REST endpoint to only send certain fields?) and depending on how your place handles security and authorizing specific calls you might not get the flexibility benefits it offers. 

 So something I should know more deeply, but have to overcome my skepticism...