0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Lantern —レトロ3D表現のためのgame engine -- chromebook debian

0
Last updated at Posted at 2026-10-17

ChromebookのLinuxターミナルの方針転換

Chromebook電源が切れてしまい、復帰後、以下、ターミナルで、解説お願いします。

NOTICE:
    Recently it has become necessary to deprecate some features of crostini,
    including:
      * UI-based installation of .deb packages. Installation via aptitude is
        the default path, but there are also visual package managers which
        may be used.
      * UI-based Debian release upgrade. Please refer to release notes for
        the release in question for upgrade instructions.
      * Multi-container support.

    For the most up-to-date news, please visit
    https://developers.google.com/chromeos/app-development/develop/news

    (this message will be repeated 4 more times).
    (to silence this message, run the following in this terminal):
        echo 10 >"/home/yourname/.local/share/cros-motd"

電源切れやシステムのクラッシュによるエラーではありませんのでご安心ください。これはChromeOSのアップデートに伴い、Googleからユーザーへ通知された公式の仕様変更のお知らせ(ターミナル起動時のメッセージ)です。

メッセージの要点は「Linux(Crostini)環境において、ChromeOS側の画面(GUI)から行っていた操作機能をいくつか廃止し、ターミナルからのコマンド操作を基本とする」という方針転換です。

具体的に非推奨(廃止予定)とされているのは以下の3点です。

  1. .deb パッケージのUIインストールの廃止
    Chromebookの「ファイル」アプリから .deb ファイルをダブルクリックしてインストールする機能がなくなります。今後はこれまで通り、ターミナルから apt コマンドを使ってインストールするか、Linux用のGUIパッケージマネージャーを導入する必要があります。
  2. UIからのDebian OSアップグレードの廃止
    ChromeOSの設定画面に表示されていた「Linuxをアップグレードする」ボタンがなくなります。OSのメジャーバージョン(例:BullseyeからBookwormなど)を上げる場合は、Debianのリリースノートに従ってターミナル上で手動アップグレードを行うことになります。
  3. マルチコンテナ機能のサポート廃止
    ChromeOSのシステム機能として複数のLinuxコンテナ(仮想環境)を並行して管理する機能が非推奨となり、標準の単一コンテナ(penguin)のみのサポートとなります。
    ※これはChromeOS側の管理機能の話であり、Linux(penguin)環境内で独自に構築・運用しているPodmanなどのコンテナには影響しません。

メッセージを非表示にする方法
このメッセージは、ターミナルを起動するたびにあと4回表示されると自然に消えます。すぐに表示させないようにしたい場合は、メッセージの指示通り以下のコマンドを実行してください。

echo 10 >"/home/yourname/.local/share/cros-motd"

ゲームエンジンlanternのビルド

以下、linux内にDownloadフォルダを作り、lua5.5.1のソースとlantern0.8のソースを解凍し、ビルドしていきます。

$ tar -xzvf lua-5.5.1.tar.gz

$ cd lua-5.5.1/

$ make

$ mkdir -p ../lua55/include

$ cp src/.h src/.hpp ../lua55/include/

cd ../lua55

$ ./lua -v

$ mkdir pkgconfig

$ cd pkgconfig

$ nano lua.pc

# 1. lua55フォルダのフルパス(バックスラッシュではなくスラッシュ「/」推奨)
prefix=/home/yokamak/Download/lantern-0.8.0/lua55

# ライブラリとヘッダーの場所(通常はprefix直下、または lib / include フォルダ内)
libdir=${prefix}
includedir=${prefix}/include

Name: Lua
Description: An Extensible Extension Language
Version: 5.5.1

# 2. -l の後は実際のライブラリファイル名に合わせます
# 例: liblua.a なら -llua / liblua55.a なら -llua55
Libs: -L${libdir} -llua

# 3. mathライブラリが必要な場合があるため -lm をつけるのが一般的です
Cflags: -I${includedir}

$ cd ../../

$ tar -xzvf lantern-0.8.0.tar.gz

$ cp -r lua55/ lantern-0.8.0

$ sudo apt install libsdl2-dev libreadline-dev

cd lantern-0.8.0/

$ export PKG_CONFIG_PATH="/home/yokamak/Download/lantern-0.8.0/lua55/pkgconfig"

$ pkg-config --cflags --libs lua

cmake -B build

cmake --build build -j8

地面、cube、sphereを配置、ライトをいくつか配置したシーンを作成してください。カメラは、原点を見る感じで、上下矢印キーで、近く遠くできるようにしてください

Wick言語の3D描画機能(lt.cube, lt.sphere, lt.plane)と、ライト(ディレクショナルライト、ポイントライト)、およびカメラ制御を組み合わせたシーンのサンプルコードです。

上下の矢印キー(UP / DOWN)でカメラの距離(ズーム)を変更し、常に原点(0, 0, 0)を見つめるように設定しています。

3Dシーンのサンプルコード (main.wick)

// ==========================================
// 1. トップレベル: 3Dメッシュの作成と変数の準備
// ==========================================
// 各種基本形状(プリミティブ)を作成します。戻り値は num 型のハンドルです[cite: 37, 43]。
let m_ground = lt.plane(10)  // 地面 (10分割の平面)
let m_cube = lt.cube()       // 立方体
let m_sphere = lt.sphere(16) // 球 (16分割)

// カメラとアニメーション用の変数
let cam_dist = 6.0           // カメラと原点との距離
let time = 0.0

fn update(dt: num) {
  // 時間を進める(ライトやキューブを回すため)
  time = time + dt

  // 矢印キーの上・下でカメラの距離を変更(ズームイン・ズームアウト)
  let zoom_speed = 5.0
  if lt.key("up") { 
    cam_dist = cam_dist - zoom_speed * dt 
  }
  if lt.key("down") { 
    cam_dist = cam_dist + zoom_speed * dt 
  }
  
  // カメラが近すぎたり遠すぎたりしないように制限[cite: 17]
  cam_dist = max(2.0, min(15.0, cam_dist))
}

fn draw() {
  // 背景を暗いグレーでクリア(3Dの描画前に必ず実行)[cite: 36, 42]
  lt.clear(0.05, 0.05, 0.1)

  // ==========================================
  // 2. カメラの設定
  // ==========================================
  // lt.camera(視点X, 視点Y, 視点Z, 注視点X, 注視点Y, 注視点Z)[cite: 36, 42]
  // 視点は斜め上 (x: 0.7, y: 0.8, z: 1.0) の方向から距離(cam_dist)を掛けた位置
  let ex = cam_dist * 0.7
  let ey = cam_dist * 0.8
  let ez = cam_dist
  // 原点 (0, 0, 0) を見る
  lt.camera(ex, ey, ez, 0, 0, 0)

  // ==========================================
  // 3. ライトの配置
  // ==========================================
  // 太陽光のような全体を照らす平行光源 (方向X, Y, Z, 環境光の強さ)[cite: 36, 42]
  lt.light(0.5, -1.0, -0.5, 0.2)

  // ポイントライト0番: 原点の周りを回る「赤い」ライト
  let light_x = 3.0 * sin(time * 2.0)
  let light_z = 3.0 * cos(time * 2.0)
  // lt.point_light(スロット0~3, X, Y, Z, 半径, R, G, B)[cite: 36, 42]
  lt.point_light(0, light_x, 1.0, light_z, 5.0, 1.0, 0.2, 0.2)

  // ポイントライト1番: 固定配置された「青い」ライト
  lt.point_light(1, -2.0, 1.0, 2.0, 4.0, 0.2, 0.5, 1.0)

  // ==========================================
  // 4. メッシュの描画
  // ==========================================
  // lt.draw(メッシュ, x,y,z, 回転x,y,z, スケールx,y,z, R,G,B)[cite: 37, 43]
  
  // 地面 (広さ10x10に引き伸ばし、少し暗い色にする)
  lt.draw(m_ground, 0, 0, 0,  0, 0, 0,  10, 1, 10,  0.4, 0.4, 0.4)

  // キューブ (左側に配置し、Y軸を中心に回転させる)
  lt.draw(m_cube, -1.5, 0.5, 0,  0, time, 0,  1, 1, 1,  0.8, 0.8, 0.2) // 黄色系

  // 球体 (右側に配置、静止)
  lt.draw(m_sphere, 1.5, 0.5, 0,  0, 0, 0,  1, 1, 1,  0.8, 0.8, 0.8) // 白色

  // ==========================================
  // 5. UI (2D描画) は最後に書く
  // ==========================================
  lt.print("UP/DOWN: ZOOM IN/OUT", 10, 10, 1, 1, 1, 1)
  
  // 距離の数値を小数点以下2桁程度で表示する工夫
  let dist_disp = floor(cam_dist * 100) / 100
  lt.print("DISTANCE: " + str(dist_disp), 10, 20, 1, 1, 0, 1)
}

3D描画のポイント

  • カメラ (lt.camera): 最初の3つの引数が「カメラの目の位置」、次の3つの引数が「どこを見つめるか(注視点)」になります。今回は注視点を常に 0, 0, 0(原点)に固定し、目の位置を cam_dist に応じて遠ざけたり近づけたりしています

  • ライト (lt.light, lt.point_light): lt.light はシーン全体を照らす太陽光です。ポイントライトは0〜3番までの4つ設置でき、今回は赤い光を回転させ、青い光を固定しています

  • 描画順序: 仕様書にある通り、「3Dの描画(lt.drawなど)を先に行い、その後に2D(lt.printなど)を描画する」ことで、3D画面の上に文字が重なるUIを作ることができます

Screenshot 2026-10-17 20.18.09.png

地面に、複数のcubeを3x3の等間隔で配置してください。7色を順に割り当ててください。

地面に3x3(合計9個)のキューブを配置し、7色を順番にループさせて割り当てるサンプルコードです。

wick(v0.3)ではリストの中にリストを入れることができないため、「RGBの各色を管理する3つの平行リスト」を作成し、インデックスを % 7 でループさせることで7色を順に適用しています。

// ==========================================
// 1. トップレベル: メッシュと色の準備
// ==========================================
let m_ground = lt.plane(10)
let m_cube = lt.cube()

let cam_dist = 10.0
let time = 0.0

// 7色(赤、オレンジ、黄、緑、シアン、青、マゼンタ)をRGBの平行リストで定義[cite: 29]
let c_r: list<num> = []
let c_g: list<num> = []
let c_b: list<num> = []

// 0: 赤
push(c_r, 1.0) push(c_g, 0.0) push(c_b, 0.0)
// 1: オレンジ
push(c_r, 1.0) push(c_g, 0.5) push(c_b, 0.0)
// 2: 黄
push(c_r, 1.0) push(c_g, 1.0) push(c_b, 0.0)
// 3: 緑
push(c_r, 0.0) push(c_g, 1.0) push(c_b, 0.0)
// 4: シアン
push(c_r, 0.0) push(c_g, 1.0) push(c_b, 1.0)
// 5: 青
push(c_r, 0.0) push(c_g, 0.0) push(c_b, 1.0)
// 6: マゼンタ
push(c_r, 1.0) push(c_g, 0.0) push(c_b, 1.0)


fn update(dt: num) {
  time = time + dt

  let zoom_speed = 5.0
  if lt.key("up")   { cam_dist = cam_dist - zoom_speed * dt }
  if lt.key("down") { cam_dist = cam_dist + zoom_speed * dt }
  
  cam_dist = max(3.0, min(20.0, cam_dist))
}

fn draw() {
  lt.clear(0.05, 0.05, 0.1)

  // カメラの設定: 俯瞰 (斜め上) から原点を見る
  let ex = cam_dist * 0.6
  let ey = cam_dist * 0.8
  let ez = cam_dist
  lt.camera(ex, ey, ez, 0, 0, 0)

  // ライトの設定
  lt.light(0.5, -1.0, -0.5, 0.3)
  lt.point_light(0, 0.0, 3.0, 0.0, 8.0, 1.0, 1.0, 1.0)

  // 地面の描画
  lt.draw(m_ground, 0, 0, 0,  0, 0, 0,  15, 1, 15,  0.3, 0.3, 0.3)

  // ==========================================
  // 3x3 のキューブ配置
  // ==========================================
  let idx = 0 // 塗る色のインデックス(0から8まで増える)

  for z in 0..3 {
    for x in 0..3 {
      // 0, 1, 2 を -2.5, 0.0, 2.5 の座標に変換して等間隔に並べる
      let px = (x - 1) * 2.5
      let pz = (z - 1) * 2.5
      
      // idx を 7 で割った余り (0〜6) を使って7色をループさせる[cite: 23]
      let c = idx % 7
      
      // lt.draw で RGB にリストから取り出した色を渡す[cite: 37, 43]
      // time を使ってすべてのキューブをゆっくり回転させています
      lt.draw(m_cube, px, 0.5, pz,  0, time, 0,  1, 1, 1,  c_r[c], c_g[c], c_b[c])
      
      idx = idx + 1
    }
  }

  // UI描画
  lt.print("UP/DOWN: ZOOM IN/OUT", 10, 10, 1, 1, 1, 1)
}

Screenshot 2026-10-17 20.29.07.png

実装のポイント

  • 平行リストによる色の管理: まとまったデータ(今回はRGBの組)を管理する際、Wickではレコードや多次元配列ではなく、対応するインデックスを持つ複数のリストを用意する「平行リスト」が基本的なイディオムです

  • モジュロ演算 (%) の活用: キューブは合計9個(idx = 0..8)ありますが、色は7種類しかありません。idx % 7 とすることで、0〜6の範囲でインデックスが循環し、7個目のキューブから再び1番目の色(赤)が割り当てられます

参考資料

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?