LuantiでLua使ってみる

LuantiはマイクラEEが今あるブロックを使って世界を作り上げるボクセルゲームであるとすると、LuantiはLuaを使ってnode(ブロック)の定義もできるしロジックの記述もできます

で、簡単なロジックを作ってみた

LuaControllerは何をやっているかというと、最初にport Bのランプを点灯させ、レバーの状態を待ち受けてonになれば、乱数でport C or Dのピストンを押し出し、1秒経過したらピストンを戻すという処理になってます

LuaControllerのLuaコードは、

port.b = true

-- Aポートからの入力を監視
if event.type == "on" and event.pin.name == "A" then
    -- 1か2の乱数を生成
    local choice = math.random(1, 2)
    
    if choice == 1 then
        -- CポートをONにする
        port.c = true
        -- 0.5秒後にOFFにする(ピストンの動作時間を確保)
        interrupt(1.0, "reset")
    else
        -- DポートをONにする
        port.d = true
        interrupt(1.0, "reset")
    end
end

-- 指定した時間が経過した後にポートをすべてOFFにする
if event.type == "interrupt" and event.iid == "reset" then
    port.c = false
    port.d = false
end

wordpressの編集でLua言語とか選択できないからPythonになってますが、特徴的なのはCPUを占有できないから(ゲーム全体が止まる)、interrupt()はイベントリスナーでタイムアウトを待っていること、この例に限らずイベントリスナーあるいはcallbackを使うのは標準になってます

次にnode定義ですが、定義の作法は、他のmodsも全て共通ですが、modsディレクトリ配下に新たなmod(ここではmaze)を定義し、mod.confファイルとluaのロジックファイルを配置します

またnodeの表面の画像表示にはstr_maze.png(32*32 dots)を用意しています、六面個別に指定もできますが、一個だけ記載すると六面全部に適用されます

・ディレクトリ構成
mods/
  maze/
    mod.conf
    init.lua
  textures/
    str_maze.png
    
・mod.conf
name = maze
description = stick-falling maze generator

ここでは何をやっているかというと、棒倒し法での迷路作成を実行しています

nodeを右クリックすると対象のエリアをクリアして、新たにnodeの石を配置して出入り口を設けるという処理

math.randomseed(minetest.get_us_time())

local function generate_maze(size)
    local maze = {}

    -- 1. 初期化:すべてを「通路(0)」にする
    for x=1,size do
        maze[x] = {}
        for z=1,size do maze[x][z] = 0 end
    end

    -- 2. 外壁と「格子状の柱」を配置
    -- 柱は 3, 5, 7... (size-2) の奇数地点に配置するのが棒倒し法の正解です
    for x=1,size do
        for z=1,size do
            if x==1 or z==1 or x==size or z==size then
                maze[x][z] = 1 -- 外壁
            elseif x%2==1 and z%2==1 then
                maze[x][z] = 1 -- 柱
            end
        end
    end

    -- 3. 棒倒し
    -- 柱(3, 5, 7...)から棒を倒す
    for z=3, size-2, 2 do
        for x=3, size-2, 2 do
            local dirs = {{0,1}, {1,0}, {-1,0}} -- 下、右、左
            if z == 3 then table.insert(dirs, {0,-1}) end -- 最初の行だけ上も許可

            -- シャッフル
            for i = #dirs, 2, -1 do
                local j = math.random(i)
                dirs[i], dirs[j] = dirs[j], dirs[i]
            end

            -- 棒を倒す
            for _, d in ipairs(dirs) do
                local tx, tz = x + d[1], z + d[2]

                -- 出入り口 (2,1) と (size-1,size) に隣接する場所は倒さない
                local is_near_entrance = (tx == 2 and tz == 1) or (tx == 2 and tz == 2)
                local is_near_exit = (tx == size-1 and tz == size) or (tx == size-1 and tz == size-1)

                if maze[tx][tz] == 0 and not is_near_entrance and not is_near_exit then
                    maze[tx][tz] = 1
                    break
                end
            end
        end
    end

    -- 4. 出入り口の最終的な穴あけ
    maze[2][1] = 0
    maze[size-1][size] = 0

    return maze
end

-- 配置関数(高さ3マスの壁を生成)
local function build_maze(pos, size)
    local m = generate_maze(size)

    for dx=0, size+1 do
        for dz=0, size+1 do
            for dy=0, 4 do
                minetest.set_node({x=pos.x+dx, y=pos.y+dy, z=pos.z+dz}, {name="air"})
            end
        end
    end

    for x=1, size do
        for z=1, size do
            local p = {x=pos.x+x, y=pos.y, z=pos.z+z}
            if m[x][z] == 1 then
                for y_off=0, 2 do
                    minetest.set_node({x=p.x, y=p.y+y_off, z=p.z}, {name="default:stone"})
                end
            else
                minetest.set_node(p, {name="default:cobble"})
                for y_off=0, 2 do
                    minetest.set_node({x=p.x, y=p.y+y_off+1, z=p.z}, {name="air"})
                end
            end
        end
    end
end

minetest.register_node("maze:maze_generator", {
    description = "迷路生成ノード",
    tiles = {"str_maze.png"},
    groups = {cracky = 1},

    on_rightclick = function(pos, node, clicker)
    	local start_pos = {x = pos.x, y = pos.y + 1, z = pos.z}
        build_maze(start_pos, 13)
    end,
})

最後のminetest.register_node()関数がnodeの登録処理で、右クリックで起動するようになっています

先にも述べた通り、全てのmodsはディレクトリ構成は全て共通なので、例えばmodsライブラリからダウンロードしてきたmodsも改造は自由にできます(例えば見え方をtexture入れ替えて変えるとか)

という感じで、自分だけのワールドの作り上げることができるのがLuantiの最大の特徴でしょう

 

admin

sesameの電池寿命はどのくらい

去年の五月に設置、その後オープンセンサーとセサミリモコン追加してますが、電池寿命に関して、

八月に追加したオープンセンサーは電池が小容量(CR1632)だけあって、割と最近寿命を迎えました

そのついでにsesame5とセサミタッチの電池電圧を測定してみた

どちらも、ほぼ5.7V(CR132AとCR2の二直)だから、リチウム電池のちょうどフラットな領域のようでまだ寿命には数ヶ月はありそうです、まあドア純正のスマートロックと併用するようにしてるから、セサミ側の電池も長持ちするようです

ちなみに昨年の秋からソフトアップデートやめたら、挙動不審状態も無くなって安定運用してるから、ローカル運用だけなら余計なアップデートはしないのが良さそうだね

電池一年持つとして、本体の寿命はせいぜい数年だろうね、まあその時点でモデル更新もあるかもしれないからちょうど買い換え適期かもしれない

 

admin

ラズパイ5でtailscaleでしかつながらない状態でtailscale downやっちまった

結果はどうなるか大体察しはつきますが、リカバリでufwの設定ファイル無効(/etc/ufwのrulesファイルをbkにrename)にしてもboot upしない(LAN scanで見る限りは見えてこない)

で、最終手段は多少古いけどsdカードのバックアップをUSB SSDにクローンした、

アクセス手段としてLANアクセスは残しとかないとまずいと気づいたから、

$ sudo ufw allow in on eth0		# 最後の手段としてLocal access可能にしとく
$ sudo ufw allow in on wlan0

$ sudo ufw reload
$ sudo ufw status numbered
Firewall reloaded

Status: active

     To                         Action      From
     --                         ------      ----
[ 1] 22/tcp on tailscale0       ALLOW IN    Anywhere                  
[ 2] 5900:5910/tcp on tailscale0 ALLOW IN    Anywhere                  
[ 3] Anywhere on eth0           ALLOW IN    Anywhere                  
[ 4] Anywhere on wlan0          ALLOW IN    Anywhere                  
[ 5] 22/tcp (v6) on tailscale0  ALLOW IN    Anywhere (v6)             
[ 6] 5900:5910/tcp (v6) on tailscale0 ALLOW IN    Anywhere (v6)             
[ 7] Anywhere (v6) on eth0      ALLOW IN    Anywhere (v6)             
[ 8] Anywhere (v6) on wlan0     ALLOW IN    Anywhere (v6)             

優先LANとWi-Fiの口は有効にしとく、

 

admin

実は壊れてなかった、ラズパイ5

経緯を整理すると、

① 途中にMacBookのrebootが入っていたと思うけど、立ち上げてもVNCに接続できないのが起点

② boot時の動作確認用のファンも回転しないので壊れたと認識して新規購入

新規購入品での挙動不審だったので色々やったけど、結局問題は、

① ラズパイ5のEEPROMが破損してたらしい(EEPROM書き込みSSDで復旧、書き換えSDで起動時の緑LEDの点滅では分かりづらいから時間待ちが確実)

新規購入品でもSDとUSB SSDを切り替えたら、また壊れたのでUSB SSDだけで運用

② VPN(tail scale)はMacBookの再起動でdown状態になるようだ、tail scale upしてるかはmagic DNS(例えば ssh pi@rasp5、rasp5.localじゃなく、を受け付ければup状態)でも状態は確認できる、tailscale statusでも良いけどね、

Expiry disabledで設定してもそのデバイスが削除されないだけで、upしていることとは別だよということ

 

①の発生原因は今のところ不明、回避方法はどちらかの媒体のみ挿入して、起動時の選択を無くする、書き換え用のSDカード常備というのは必要そうである

 

以上の結果から、もしやと思って古い方のラズパイ5にEEPROM書き換え実行して、tailscale up状態でVNC接続、つまり正常動作、を確認できたから実は壊れたと勘違いしてたようだ

②の永続化(rebootで自動up)するためには、

brew install --formula tailscale
sudo brew services start tailscale
sudo tailscale up

最後のupでwarning出るけど無視して良いようだ、sudo tailscale upでsudoが必要なのはデーモンモードだから、アプリ版ならsudoは不要

% sudo tailscale up
Warning: client version "1.94.2-t2de4d317a" != tailscaled server version "1.94.2-t0a29cf18b-g3f044c9f6"

 

予備機ができたから使い道考えよう、ヘッドレス運用というのはネットワーク経由とオンボードのLEDしか稼働状態判らないのがネック

 

admin

ラズパイ5壊れた、新規購入

突然死したので新規購入、電源ONでboot upしなくなりました、緑LEDが点灯しっぱなし状態

SDカード、USB SSDどちらも媒体にアクセスしに行かない

下が壊れたラズパイ5、上が購入品、冷却ファンだけは使い回しできそうなので外して保存しときます、サーマルパッドは一度外すと新規に取り付けしないと期待した性能にはならないだろうし

しかし去年の一月末購入で24時間かどうでもないのに逝ってしまうのはハズレだったんだろうね

 

admin

Libreofficeの削除

VMware上で動かしているUbuntu、デフォでLibreoffice入っているけど使うことないから削除

https://ja.console-linux.com/?p=21730

24系でも上の通りで削除できた、

$ sudo apt-get remove --purge libreoffice*

$ sudo apt clean

$ sudo apt-get autoremove

3GBぐらいSSD領域削減できたかもしれない

 

admin

VMwareでUbuntu起動時の待ち(デフォルト2分)

タイトル通りですが、Ubuntu更新後のVM再起動時に必ず2分も待つので無駄だろうから、聞いてみると特にUbuntuとVMwareの組み合わせでは問題ないようでsystemdを無効化した

$ sudo systemctl disable --now systemd-networkd-wait-online.service 

で2分待ちを解除するとサクサク立ち上がった、ネットワークの安定化待ちのようですね、2分も待つのという感じですが

 

admin

Carbon Copy Cloner(CCC)を使う

USB SSDで細かな時間間隔でtimemachineバックアップ、USB HDDには例えば一週間単位ぐらいでのバックアップを考えた時にtimemachineよりも、Carbon Copy Cloner(CCC)の方が完全クローンだから復元が楽だろうと思うから、HDD側にクローン作成した

https://bombich.com

無償期間は30日ですが、完全クローン作成や復元ならば無償期間終了しても使えるようです

初期画面でコピー元はMacのSSD、コピー先にはUSB HDDのバックアップパーティションを指定するといくつかの手順は必要ですが、バックアップを開始します

およそ2時間弱でクローンの作成完了、発見済みが1.8Tぐらいになっているのですが実際にコピーされるのは、

無論Macで使われている領域だけ、完全クローンなので復元も確実だろうと思う、作業は手動で起動になりますが

P.S. 2026/3/5

書き込みベリファイを追加

時間はかかるけど、書き込みデータのチェックはした方が良さそうなので、設定で「コピーされたファイルを再確認」にチェック入れる

 

admin

NASやめたのでUSB HDDにもtimemachineバックアップを取る

あまりに遅すぎて捨てた2021年エントリーモデルのNAS(qnap TS-230)、そこに時間限定運転で使ってたHDD(WD 6TB)はほとんど稼働時間ないから、USB 3.2のHDDケース購入(GW3.5AM-SU3G2P)してバックアップ用にしてみた

媒体チェックはMacのFirst Aidでは今時点は問題なし、

これで問題あるならほぼ終わりだろうけど、

timemachineで6Tは必要ないからパーティション切って3Tをtimemachineに割り当て、

HDDのベンチマークでシーケンシャルread 200MB/sちょい、write 150MB/sあたりなのでNASに比べるとかなり早い、フルバックアップ(およそ500GB)も一時間程度で終了したから、これがNASだと6時間ぐらいかな

USB SSDは定時バックアップで、USB HDDは週一ぐらいの運用でいくかな、SSD/HDD両方をバックアップデバイスにしてしとくと交互にバックアップするらしいけどね、

 

admin

TigerVNCで一般ユーザの専用デスクトップを持たせる

実現する形態、

<ラズピコ5はサーバー運用>

・Luantiサーバー(ユーザー接続はtailscaleを使う)

・管理者:サーバー運用とユーザー管理

・一般ユーザー:ユーザーごとにLuantiサーバーを起動、つまり個別のワールドを持てる様にして、デスクトップも分離させて持たせる

<目的に合いそうなVNCサーバー>

TigerVNCがピッタリ感



tigervncのインストール、
$ sudo apt install tigervnc-standalone-server tigervnc-common -y

アカウント(luanti1)を作る、

$ sudo adduser luanti1

$ groups luanti1
luanti1 : luanti1 users

$ tigervncpasswd // tigervncのpw設定する(tigervnc login時必要)

<設定ファイル:サービスの定義>

luanti1@rasp5:~ $ cat ~/.config/systemd/user/tigervnc@.service
[Unit]
Description=TigerVNC Server
After=network.target

# direct to the user directory
[Service]
Type=forking
ExecStartPre=/bin/rm -f /home/luanti1/.vnc/%H:%i.pid		

ExecStart=/usr/bin/tigervncserver %i -geometry 1280x800 -localhost no -SecurityTypes VncAuth,TLSVnc -xstartup /home/luanti1/.vnc/xstartup

ExecStop=/usr/bin/tigervncserver -kill %i
Restart=on-failure

[Install]
WantedBy=default.target

<設定ファイル:サービス起動設定>

luanti1@rasp5:~ $ cat ~/.vnc/xstartup

#!/bin/bash
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS
exec dbus-launch --exit-with-session startlxde-pi

<ブート時自動起動の設定>

ユーザごとにログインして以下を実行する、

サーバーでboot時に有効にするなら、
# linger有効化(一般ユーザでやれば他人は変更できないからそれがお勧め)
$ loginctl enable-linger username        // usernameは実際のユーザ名(ここではpi)に置き換え
# userサービス enable
$ systemctl --user enable tigervnc@:1
# 今すぐ起動
$ systemctl --user start tigervnc@:1

ステータス確認、
$ systemctl --user status tigervnc@:1
● tigervnc@:1.service - TigerVNC Server
~~以下略

 $ ss -tlnp | grep 5901
LISTEN 0      5                          0.0.0.0:5901       0.0.0.0:*    users:(("Xtigervnc",pid=203908,fd=7))
LISTEN 0      5                             [::]:5901          [::]:*    users:(("Xtigervnc",pid=203908,fd=8))

tigervnc@:1はそのユーザーの仮想画面番号を指定する

 

VNCクライアントの管理画面はこんな感じ、

・LAN内のアクセスは禁止している

・予備のためにRealVNC(port 5900:piのみ接続可能)は活かしてある

・TigerVNCの画面はport 5901(pi用)/5902(luanti1用)を用意してある

以上で複数ユーザーがユーザーごとにLuantiサーバーの起動とデスクトップ画面の使用できる様な環境設定を完了、sshも許可してるからそれは非常用かな

 

admin