Peace For All – Re: Factor

Peace For All – Re: Factor

Peace For All Wednesday, July 8, 2026 #games #text #ui Peace For All 2026年7月8日,星期三 #游戏 #文本 #UI

I am perhaps susceptible to nerd-sniping and it often leads me down interesting rabbit holes. Today was one of those days. I bumped into a fun article about some obfuscated bash code on a T-shirt for sale: The obfuscated code in question is actually an easter egg, it’s being supplied via Uniqlo stores on an excellent t-shirt designed by Akamai in support of their Peace for All campaign. 我可能很容易被“极客陷阱”(nerd-sniping)吸引,这经常让我陷入有趣的深坑。今天就是这样的一天。我偶然发现了一篇关于一件在售 T 恤上混淆 Bash 代码的有趣文章:文中所述的混淆代码实际上是一个彩蛋,它出现在优衣库(Uniqlo)门店销售的一款由 Akamai 设计的精美 T 恤上,旨在支持他们的“Peace for All”公益活动。

While reading about the author’s use of OCR to convert the printed text into a string that they could compute base64 —decode on to see the resulting program, I had major nostalgia for carefully typing programs from computer magazines so they could be run locally – the only option for us kids at the time. 在阅读作者如何利用 OCR(光学字符识别)将印刷文本转换为字符串,并对其进行 base64 --decode 解码以查看最终程序的过程中,我怀念起当年小心翼翼地从计算机杂志上敲入代码以便在本地运行的日子——那可是我们这代孩子当时唯一的选择。

Raylib can be a great tool for doing colorful animations and is pretty well supported by Factor. I thought it would be fun to show how to write a similar program using it! First, we define some constants for our message (infinitely looping using a circular sequence), font sizes, text colors, and then a computed number of visible text rows: Raylib 是制作炫彩动画的绝佳工具,并且得到了 Factor 语言的良好支持。我想展示一下如何用它编写一个类似的程序应该会很有趣!首先,我们为消息(使用循环序列实现无限循环)、字体大小、文本颜色定义一些常量,并计算可见文本的行数:

CONSTANT: message $[ "♥PEACE♥FOR♥ALL" <circular> ]
CONSTANT: width 800
CONSTANT: height 600
CONSTANT: font-size 24
CONSTANT: freq 0.2
! colors move from cyan to orange
CONSTANT: color-start S{ Color f 0 255 255 255 }
CONSTANT: color-end S{ Color f 255 135 0 255 }
: rows ( -- n ) height font-size /i ;

The default font doesn’t include a heart glyph, so we need to be able to manually draw one: 默认字体不包含心形符号,因此我们需要手动绘制一个:

:: draw-heart ( x y color -- )
    font-size :> s
    x s 0.30 * + >integer y s 0.32 * + >integer s 0.22 * color draw-circle
    x s 0.70 * + >integer y s 0.32 * + >integer s 0.22 * color draw-circle
    x s 0.50 * + y s 0.95 * + <Vector2>
    x s 0.92 * + y s 0.42 * + <Vector2>
    x s 0.08 * + y s 0.42 * + <Vector2> color draw-triangle ;

Otherwise, we draw our character as a function of a “tick”, moving horizontally in x according to a sine wave, and changing colors within our color range: 此外,我们将字符绘制为“滴答”(tick)的函数,根据正弦波在水平方向(x轴)移动,并在颜色范围内改变颜色:

: wave-x ( tick -- x )
    freq * sin width 4 /i * width 2 /i + round >integer 0 width font-size - clamp ;

: wave-color ( tick -- color )
    [ color-start color-end ] dip rows mod rows /f color-lerp ;

:: draw-glyph ( tick row -- )
    tick wave-x :> x
    row font-size * :> y
    tick message nth :> ch
    tick wave-color :> color
    ch CHAR: ♥ = [ x y glyph color draw-heart ] [ ch 1string x y font-size color draw-text ] if ;

We can now define a rendering function that we use each tick, that draws a glyph on each row: 现在我们可以定义一个在每个“滴答”时调用的渲染函数,在每一行绘制一个字符:

: render ( tick -- )
    begin-drawing BLACK clear-background
    rows <iota> [ [ + ] keep draw-glyph ] with each
    end-drawing ;

And then a simple loop where we open a window, and increment the tick and render each frame: 接着是一个简单的循环:打开窗口,增加“滴答”计数,并渲染每一帧:

: open-peace-window ( -- )
    width height "♥ PEACE FOR ALL ♥" init-window 30 set-target-fps ;

: peace-for-all ( -- )
    open-peace-window 0 [ window-should-close ] [ [ 1 + ] [ render ] bi ] until drop close-window ;

It looks pretty good! The code for this is on my GitHub. 效果看起来很不错!代码已上传至我的 GitHub。