3 of 5 added 111 characters in body

Chip, 174 166 106 bytes

103 bytes for the code + 3 bytes for the flag (-w)

|z. b--((^e
`{*    e

Try it online!

Chip is a 2D language inspired by integrated circuits, input and output are broken down into individual bits which travel through gates and across wires.

Ungolfed (144 bytes):


How the ungolfed version works:

This implementation encodes the target string Hello, World! as a bit matrix, somewhat reminiscent of core memory. The leftmost column of )'s and x's corresponds to H in the output, the rightmost column to !. The ) is an Or-gate (mapping to a 1 in the output), and the x is a wire crossing (mapping to a 0).

The first three rows are for timing, and the remaining rows are for each of the bits of the output (the row ending in h is the highest bit, and a is the lowest).

The timing behavior starts with the first row. * produces an always-on signal, which is delayed one cycle by the Z. The output of the Z is inverted by the NOT-gate ~. The resultant output of this contruct is a 1-cycle pulse at the beginning of execution. Wire elements guide this signal down to the rest of the circuit. The rest of Zs control the left-to-right propagation of the signal at a rate of one element per cycle, each one corresponding to the transition between consecutive letters of the output. Each Z also sends a signal to the column below. At the end of the timing row is t, which terminates the program, preventing infinite output of null characters at the end.

In the first cycle, the first data column is powered. We see OR-gates ()) on the rows for bits d and g, turning them on; the remaining bits stay off because the wire crosses (x) won't propagate the signal from the top to the left. This gives us 01001000, which is H.

In the next cycle, only the second data column is powered. Rows a, c, f and g turn on much like the bits in the first cycle, and the remaining bits are off. This gives us 01100101, which is e.

This continues all the way across to the right, giving the remainder of the output.

Golfing it:

There's not a lot that could be done here, but there are a few things of note:

  • The h row is always off, so that can be eliminated.
  • Each row can be trimmed on both ends, removing unnecessary x's, so long as the timing signal can still be propagated downward to rows that need it below. This is why the rows are rearranged; to maximize the trimming that can occur.
  • The timing initialization portion (first two rows of the ungolfed version) can be moved to the empty space freed up by the aforementioned trimming.
  • The construct )a is equivalent to simply a, so long as the signal did not need to be propagated downward from the OR-gate.

All other changes are just mashing things around to save single bytes.