令和8年8月8日午後8時から88時間限定*1で公開します。
初回アクセス時にややくどい表示が出ますので一応読んでください。命令一覧等へのリンクはページ内にあります。
STN-BASIC:サンプルゲーム1
穴掘り法による迷路ゲームで、毎回固定の全8フロアです。
右下のマスがゴール。
※そこまでボリュームはないですが、セーブ機能はないため暇なときに遊んでください。
'--------------------------------------------
'@#NAME:SAMPLE GAME NO.1
'--------------------------------------------
'<<[!USE STDLIB]>>
'↑この行のみ、動作に影響しますので省かないでください。ほかのコメント行は省略OK
SETBTREPEAT 16
VAR B,I,R,X,Y
VAR BX,BY
VAR GX,GY
VAR OX,OY
VAR PX,PY
VAR SX,SY
VAR NOW_FLOOR
'********************************************
VAR KR
DEF KRANDOMIZE SEED
KR=SEED
END
DEF KRND() 'クロサワ式乱数
KR=KR XOR &H9630
KR=KR-&H6553 AND &HFFFF
KR=((KR<<2) OR (KR>>14)) AND &HFFFF
RETURN KR
END
DEF SRND(M)
RETURN KRND() MOD M
END
'********************************************
ACLS
SPSET 64,304:SPOFS 64,23*16,13*16
DIM MYSP,WALL,ANIMCNT=0,ANIMCHR=0
DIM MVX,MVY
DIM ANIMX=0,ANIMY=0
RESTORE @CHARACTER
READ MYSP,WALL
FOR NOW_FLOOR=1 TO 8
SX=13:SY=8
GOSUB @MAZE
CLS
?NOW_FLOOR;"F"
PX=16:PY=16
SPSET 0,MYSP
SPOFS 0,PX,PY,-1'実際はZ座標は無視
'BGMは未実装なので略
WHILE !GOALCHK()
VSYNC 1
B=BTRIG()
IF ANIMCNT>0 THEN
SPCHR 0,ANIMCHR
INC ANIMX,MVX:INC ANIMY,MVY
SPOFS 0,ANIMX,ANIMY
DEC ANIMCNT
IF ANIMCNT MOD 4==0 THEN INC ANIMCHR
CONTINUE
ENDIF
IF B==0 || ANIMCHK() THEN CONTINUE
OX=PX:PX=PX+(!(4AND B)-!(8AND B))*16
OY=PY:PY=PY+(!(1AND B)-!(2AND B))*16
IF BGGET(1,PX/16,PY/16) THEN PX=OX:PY=OY
IF BGGET(1,OX/16,PY/16) THEN PX=OX:PY=OY
IF BGGET(1,PX/16,OY/16) THEN PX=OX:PY=OY
IF PX==OX && PY==OY THEN CONTINUE
MVX=SGN(PX-OX):MVY=SGN(PY-OY)
IF B AND 2THEN SPCHR 0,MYSP+4
IF B AND 4THEN SPCHR 0,MYSP+8
IF B AND 8THEN SPCHR 0,MYSP
IF B AND 1THEN SPCHR 0,MYSP+12
IF B AND 15 THEN
ANIMCNT=15
ANIMCHR=SPCHR(0)
ANIMX=OX+MVX:ANIMY=OY+MVY'初回分移動量
SPOFS 0,ANIMX,ANIMY
ENDIF
WEND
'BGM(ジングル)は未実装なので略
NEXT
BGCLR 0:BGCLR 1:SPCLR 64:CLS
?"GAME CLEAR!"
?"THANK YOU FOR YOUR PLAYING!"
END
DEF ANIMCHK()
RETURN ANIMCNT!=0
END
DEF GOALCHK()
RETURN !ANIMCHK() && PX==23*16 && PY==13*16
END
DIM TPX,TPY
@MAZE
KRANDOMIZE 17*NOW_FLOOR+16
DIM T[SX*2,SY*2]
DIM P[0]
BX=SRND(8)*2+5
BY=SRND(5)*2+5
FILL T,1
BGCLR 0:BGCLR 1
WHILE 1
IF GET(BX-2,BY)!=1 && GET(BX+2,BY)!=1 && GET(BX,BY-2)!=1 && GET(BX,BY+2)!=1 THEN
IF MAX(P)<0 THEN BREAK
REPEAT
'乱数生成で次アドレス
I=SRND(LEN(P)/2 OR 0)
UNTIL P[I*2]>=0
BX=P[I*2]
BY=P[I*2+1]
P[I*2]=-1
P[I*2+1]=-1
CONTINUE
ENDIF
R=SRND(4)'ほうこうせってい
IF R==0 THEN GX=-1:GY=0
IF R==1 THEN GX=1:GY=0
IF R==2 THEN GX=0:GY=-1
IF R==3 THEN GX=0:GY=1
IF BX+GX<1||BY+GY<1 THEN CONTINUE
IF BX+GX>SX*2-3||BY+GY>SY*2-3 THEN CONTINUE
'注:二次元配列の添字は式を認識しないので変数に代入する
'また、二次元の添字は 宣言 if 代入のどれか以外では認識しない
TPX=BX+GX*2:TPY=BY+GY*2
IF T[TPX,TPY]==1 THEN
T[BX,BY]=0'移動前のマス
INC BX,GX:INC BY,GY:T[BX,BY]=0'途中のマス
INC BX,GX:INC BY,GY:T[BX,BY]=0'移動完了
PUSH P,BX
PUSH P,BY
ENDIF
WEND
FOR Y=0 TO SY*2-2
FOR X=0 TO SX*2-2
B=T[X,Y]
BGPUT 0,X,Y,103
BGPUT 1,X,Y,B*WALL
NEXT
NEXT
RETURN
@CHARACTER
DATA 756 'MY SPRITE
DATA 107 'WALL BG : 163に変えると木になります
DEF GET(X,Y)
IF X>=0 && X<SX*2-1 && Y>=0 && Y<SY*2-1 THEN
RETURN T[X,Y]
ELSE
RETURN 0
ENDIF
END※THENやANDの前後で詰めているのは、そう書いても動くことを確かめる意図的なものです。
特定のキーワードのみピンポイントで省略されたスペースを補うので、基本的にアルファベットの演算子の前後は空けてください。
STN-BASICの作例
こんなものが動く予定、というサンプルを載せていきます
※素材バンク変更のため、一部修正しました(8/7)
※マウス入力のサンプルを追加(8/7)
※名称が決まったため記事タイトル変更(8/7)
※スプライトのテンプレート番号が標準ライブラリと被るので変更(8/8)
スプライト歩行テスト
操作に関係なくスプライトが下→右→下→右…と歩き、画面下端まで行くと終了します。
ACLS DIM Q=4,PY=0 GOSUB @SUB Q=0:PY=32 GOSUB @SUB SPSET 2,&H100+4 DIM I,W,X=128,Y=0 WHILE Y<240 ?Y FOR I=0 TO 3 SPCHR 2,&H100+4+I FOR W=1 TO 16 IF W MOD 4==0 THEN INC Y:SPOFS 2,X,Y VSYNC 1 NEXT NEXT FOR I=0 TO 3 SPCHR 2,&H100+I FOR W=1 TO 16 IF W MOD 4==0 THEN INC X:SPOFS 2,X,Y VSYNC 1 NEXT NEXT WEND END @SUB SPDEF &H100+Q,"SPU0",48*2+16,PY,16,16 SPDEF 1+&H100+Q,"SPU0",48*2+16*0,PY,16,16 SPDEF 2+&H100+Q,"SPU0",48*2+16,PY,16,16 SPDEF 3+&H100+Q,"SPU0",48*2+16*2,PY,16,16 RETURN
動作例:

マウス入力のサンプル(超簡易ペイント)
Tabキーで終了。色は白とピンクとマゼンタで、マウスの押すボタンで決まります。
ACLS REPEAT VSYNC CLS ?TCHX ?TCHY ?TCHST IF TCHST>0 THEN GPSET TCHX,TCHY,RGB(255,255-255*(TCHST-1)/2,255) UNTIL BUTTON(0)==32
スクリーンショットに使用した著作物に関する表示
スプライトは著作権者「Lanea Zimmerman」による素材「Tiny 16: Basic」(ライセンスCC-BY 3.0ほか)のcharacters.pngを使用
入手元:opengameart.org
フォントは「美咲フォント」を使用。ライセンスは下記ページ内を参照
入手元:littlelimit.net
開発中のお知らせ
2010年代のゲーム機向けBASICと似たような文法で書くことができる小規模なBASIC言語の実行環境を開発しています。
その名は「STN-BASIC」だとか。ブラウザで動きます。
独自圧縮フォーマット(ADE:ArrayDictionaryEncode)に関するメモ
説明は飛ばして、バリエーションを一通りまとめるだけ。
具体的な仕様はプログラムが全て(いつものやつ)
用語
分割数:配列1要素(32bit)をいくつに区切って使うかの数
塊:配列1要素を指定した分割数で区切った値1個のこと。4分割ならちょうど1byteになる
追加圧縮:ADEの別名。もとはSRD画像フォーマットの一部なのでそう呼んでいたが、後にADE単独で使うようにもなった
バージョン値:『SRD画像圧縮ライブラリ』のwiki記事を参照。&h23→&h20という変な順番なのは、ASCII文字として解釈した時それぞれ『#』、スペースになる値を付けたから
初期版ADE(バージョン値:&h23)
参照が成立しない値をそれぞれ1塊として記録していたので、ランダムに近いデータはとても肥大する。
NEW_ADE(バージョン値:&h20)
初期版から「参照が成立しない値」が連続した数を記録するように変えたため、ランダムに近いデータがほとんど肥大しなくなった。
『SRD画像圧縮ライブラリ』の2022/06/01の更新記録にある「PackBits的なロジックを加える」というのはこの変更のこと。
細かいことをいうと2バージョン存在する(参考:2022/06/10の更新記録)
ADC
手元には存在するが非公開の模様。
NEW_ADEとの違いは参照不成立連続数の表現が違う(参照成立時の参照位置が常に1塊の代わりに、0,連続数の2塊で記録)ことらしい。
おそらくNEW_ADEと比べて圧縮率の差が少ない以前に、デコーダのバグを発見できず修正ができなかったので没になった。
XADE
NEW_ADEデコーダをJavaScriptへ移植するにあたり、計算過程で出る値が必ず非負になるようにビット演算を乗除算に変更したもの。
ついでに、2の冪でない分割数*1を指定できるよう手を加えて実験したものの、圧縮率がほとんど優れていないのでこの変更点は没になった。
分割数が2の冪であるときの圧縮データはNEW_ADEと全く同じ。
ところで、初期の頃は月に複数回規格が変わるような有様なので、おちおち使えない感じでしたね。
今はめったに改定しないので安心して使えますね(?)
更新(大きな変更のみ)
- 4/10…ADCとXADEの制作経緯がほとんど嘘なことが分かったので修正。
*1:この場合、プログラムの簡略化のため端数のbitは使わない(たとえば3分割だと10bit×3ごとに、あまりの2bitは未使用)
ATAMA_EXPLORERで使っている独自符号化の解説
確か、プチコン3号まとめwikiに掲載した記憶があるのだが
アーカイブをいくら探しても見つからないので、今後のアップデートで追加する符号種類を含めて軽くまとめておく
現在の最新の規格は2026-01-20に発効したバージョン『3.5(2026.1)』です
符号の種類
AC…ASCII Character
名前のまま。U+0000からU+007Fまでの文字は、シンプルに1オクテットで符号化する。
ただし、ETC・TTC・RLCで符号化できる文字列は、ACとして符号化してはならない。
NAC…Non ASCII Character
これも名前のまま。U+0080以降かつETC・TTC・RLCで符号化できない文字を符号化する。3オクテット。
当然のことながら、ACで符号化できる文字は、NACとして符号化してはならない。
ETC…Extra Token Character
特徴的な符号の種類で、プチコンのプログラムによく出現する"DIALOG"や"DISPLAY"などの単語を1文字であるかのように符号化することで、圧縮効果を発揮する。2オクテット。
頻出する英単語のほか、ひらがな・カタカナ*1と句読点も含まれる。
TTC…Triple-1 Token Character【バージョン3.5(2026.1)で追加】
ETC同様、頻出する単語を1文字のように表現するが、元が2文字の"IF"などがETCでは圧縮できないため効率向上を意図して作られた符号の種類。ETCの空き符号に無理やりねじ込んで1オクテットで符号化する。
名前は、2進数で表記した時に左の3桁が1になることに由来する。
変更履歴(符号の種類について)
2026-01-20
- RLC(Run-Length Character)を完全に規格から削除した。
勝手にFAQ
独自符号全体に名前は無いのですか?
初期から存在した符号の種類の頭を取って"ANETコード"という名前を考えているが、同じ読みの単語が既に存在するため正式には「名前がない」状態
プログラム名の一部を冠した『AT-ANETコード』を正式な名前に決定。
プチコン3号用OSMレンダラもどきの開発を緩くまとめる
この記事は『OpenStreetMap - Qiita Advent Calendar 2025 - Qiita』の14日目の記事です
前提:プチコン3号とは
公式サイトを見る方が早いので(投げやり)
一言でいえば3DS用のプログラム開発環境(とても合法*1)です
smilebasic.com
4月 - 6月
4月30日。プチコン作品でおそらく*2初めて、osmファイルからウェイとノードの座標を取り出して地物の輪郭を表示した

座標の解釈に誤りがあるので、実は鏡映し(左右反転になっている)
Map data © OpenStreetMap contributors | Copyright and License | OpenStreetMap
※以下の各スクリーンショットは同ライセンスの地図データによる

6月6日に「SVG EDITOR」ver.1.0として公開
petitcom.mitsutan.dev
12月 - 記事投稿
6月時点では地物の表示だけで満足していたが、どうせなら表示だけじゃなくてマッピング機能を付けようという機運が出てきたので開発を再開

画面座標から経緯度へ換算する式をあり得ない方法で求めながら(開発中のつぶやきのツリー)

詳細の入力は、3DSという端末でやるにはヘビー*3なので、よくあるブランドをプリセットから選ぶ形にしました

ただし、これは手元のOSMファイルに書き込むだけの機能。プチコンの制約*4のため、OSMのサーバーにデータをアップロードすることはできない
そこで、変更点をLevel0L形式*5に整え、二次元コードとして表示。それをスマートフォンなどの他端末で読み取る、という少し面倒なやり方でサーバーへのアップロードを実装する予定です(記事投稿時点で、Level0L出力の手前まで実装完了)
実際のアップロードができたら、新しい記事で続報を書く…かもしれない