**Show HN:** 長時間戦略ゲーム「FreeCiv」を友人とプレイする

2026/03/19 4:01

**Show HN:** 長時間戦略ゲーム「FreeCiv」を友人とプレイする

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

要約

本書は、Freeciv Longturn サーバー(Freeciv 3.2.3)を Fly.io 上でデプロイし運用する方法を説明しています。単一の Docker コンテナがポート 5556 で

freeciv-server
を実行し、BusyBox HTTP プロキシが
/tmp/server-input
からライブステータスページを提供します。
永続データは
/data/saves
に保存され、圧縮されたゲームセーブファイル(
lt-game-*.sav.gz
)、SQLite 認証 DB(
freeciv.sqlite
fcdb.conf
database.lua
で設定)および JSON ファイル(
status.json
history.json
attendance.json
diplomacy.json
gazette.json
)が含まれます。
コアスクリプトは次の通りです:

  • entrypoint.sh → start.sh
    でサーバーを起動します。
  • longturn.serv
    は 23 時間のターン、10 時間のユニット待機時間、および ALLIED 勝利条件を設定します。
  • generate_status_json.sh
    は cron により 5 分ごとに実行され、クライアントが描画するステータス JSON(ランキング、チャート、外交、カウントダウン、ガゼット)を生成します。
  • メールユーティリティ(新ターン開始の
    turn_notify.sh
    、2 時間締切の
    turn_reminder.sh
    )は
    email_enabled.settings
    で制御されます。
  • プレイヤー管理は
    manage_players.sh
    により行われ、SQLite 認証 DB とサンプル
    players.conf
    を使用します。
  • その他ヘルパー:
    fix_turn_timer.sh
    (締切の上書き)、
    change_gold.sh
    (金額調整)、
    generate_gazette.sh
    (OpenAI 搭載新聞生成)、
    generate_nations.sh
    (国リストページ生成)。
    サーバーは再起動時にセーブファイルから
    phase_seconds
    値を読み取り、残り時間を再計算することでターンタイマーを保持します。
    デプロイは Fly.io の CLI、Dockerfile、および保存用永続ボリュームをマウントした
    fly.toml
    設定で行い、シークレットには SES SMTP 資格情報と OpenAI API キーが保管されます。
    代表的な操作は:
    fly deploy
    、コンテナへの SSH 接入、強制セーブ、ステータス JSON 再生成、金額変更、締切上書き、メールトグル、アプリ再起動などです。

この改訂要約はリストの主要ポイントをすべて網羅しつつ、主旨を明確に保ち、曖昧な表現を避けています。

本文

Freeciv Longturn Server

自己ホスト型の Freeciv 3.2.3 マルチプレイヤーサーバーで、長時間ターン(23 時間)を想定しています。
Fly.io 上で動作し、メール通知・ライブステータスページ・AI が生成する新聞機能があります。

  • ライブデモhttps://freeciv.andrewmcgrath.info
  • 現在 16 人が参加しているアクティブゲームが稼働中です。ライブランキングやターンカウントダウン、ヒストリーチャート、外交追跡、AI が作成した戦時新聞などはステータスページでご確認いただけます。

Longturn とは?

Longturn は Freeciv のマルチプレイヤー形式の一つで、1 ターンが数分ではなく約 23 時間続きます。
プレイヤーは毎日ログインし、行動を決定したら Turn Done をクリックして生活に戻ります。
全員がターン終了(またはタイマー切れ)すると次のターンへ移行します。


アーキテクチャ概要

┌─────────────────────────────────────────────────┐
│  Fly.io コンテナ                               │
│                                                 │
│  entrypoint.sh                                  │
│    ├── busybox crond (ステータスページ更新)   │
│    └── start.sh                                 │
│         ├── freeciv-server (ポート 5556)          │
│         ├── busybox httpd (ポート 8080 → 80/443) │
│         ├── FIFO コマンドライター                │
│         ├── Turn change watcher                  │
│         ├── Auto‑saver (5 分ごと)               │
│         └── Turn reminder checker               │
│                                                 │
│  /data/saves (永続ボリューム)                   │
│    ├── lt-game-*.sav.gz   – セーブファイル      │
│    ├── freeciv.sqlite      – プレイヤー認証DB   │
│    ├── status.json         – ライブゲーム状態  │
│    ├── history.json        – ターンごとの統計  │
│    ├── attendance.json    – 欠席したターン     │
│    ├── diplomacy.json     – 関係性             │
│    └── gazette.json       – AI 新聞記事         │
└─────────────────────────────────────────────────┘

サーバーは FIFO パイプ (

/tmp/server-input
) を介して通信します。
スクリプトはこのパイプに書き込むことで実行中の Freeciv サーバーへコマンドを送ります。


スクリプト

スクリプト目的
entrypoint.shコンテナ起動時のエントリーポイント。crond を開始し、権限を下げて
start.sh
を実行します。
start.shメインオーケストレーター。Freeciv サーバー、FIFO パイプ、自動セーブ、ターンウォッチャー、リマインダー・ループ、HTTP サーバーを起動し、再開時のタイマー継続ロジックも処理します。
longturn.servゲーム設定:23 時間ターン、10 時間 unitwaittime、同盟勝利のみ、プレイヤーリストなど。

ステータスページ

スクリプト目的
generate_status_json.shセーブファイルからゲーム状態を抽出し JSON に変換します。cron(5 分ごと)とターン変更時に実行され、
status.json
history.json
attendance.json
diplomacy.json
を生成します。
www/index.htmlクライアント側ステータスページ。JSON を取得してランキング、チャート(Chart.js)、外交、カウントダウンタイマー、新聞記事を描画します。
www/cgi-bin/healthヘルスチェックエンドポイント。
status.json
が 7 分以上古い場合は 503 を返します。監視ツールで利用。

通知

スクリプト目的
turn_notify.sh新しいターン開始時に全プレイヤーへ HTML メールを送信。ランキング表、新聞記事、締切情報が含まれます。
turn_reminder.sh60 秒ごとに実行。締切の 2 時間前までに「Turn Done」をクリックしていないプレイヤーへリマインドメールを送ります。
turn_notify.luaFreeciv のシグナルハンドラで、ターン変更時に
turn_notify.sh
をトリガーします。

プレイヤー管理

スクリプト目的
manage_players.shSQLite 認証 DB にプレイヤーアカウントを作成し、ウェルカムメールを送信、プレイヤー一覧を表示します。
fcdb.conf / database.luaSQLite 認証 DB の設定と初期化。

ユーティリティ

スクリプト目的
fix_turn_timer.shターン締切を特定の時刻(例:
./fix_turn_timer.sh 4
)にオーバーライドします。次ターンでは通常の 23 時間タイムアウトに戻ります。
change_gold.shLua コマンドでプレイヤーの金額を調整 (
./change_gold.sh andrew 50
)。
generate_gazette.shOpenAI を呼び出し「The Civ Chronicle」を生成。各ターンごとに時代に合った不正確な戦時新聞記事を作成します。
generate_nations.sh利用可能な全国一覧の静的 HTML ページを生成します。
local_preview.shセーブファイルデータでローカルにステータスページをプレビューします。

設定ファイル

ファイル目的
email_enabled.settings
true
/
false
により全メール通知を有効/無効化します。
crontabcron スケジュール。5 分ごとに
generate_status_json.sh
を実行。
fly.tomlFly.io デプロイ設定(リージョン、VM サイズ、ポート、ボリューム)。
Dockerfileマルチステージビルド:Freeciv 3.2.3 をソースからコンパイルし、軽量ランタイムイメージを作成。

セットアップガイド

前提条件

  • Fly.io CLI (
    flyctl
    )
  • Docker(ローカルビルド/テスト用)
  • AWS アカウントに SES を設定済み(メール通知用)
  • OpenAI API キー(AI 新聞機能オプション)
  1. クローン&設定

    git clone <repo‑url>
    cd freeciv-server
    cp .env.sample .env
    

    .env
    を編集し認証情報を入力します:

    SES_SMTP_USER=your-ses-smtp-username
    SES_SMTP_PASS=your-ses-smtp-password
    SES_SMTP_HOST=email-smtp.us-east-1.amazonaws.com
    OPENAI_API_KEY=your-openai-key  # optional, for gazette
    
  2. ゲーム設定をカスタマイズ

    longturn.serv
    を編集:

    timeout 82800          # ターン長(秒) 23 時間
    unitwaittime 36000     # ダブルムーブ防止 10 時間
    victories ALLIED       # 勝利条件
    

    プレイヤーコマンドを末尾に追加。

  3. プレイヤー追加

    cp players.conf.sample players.conf
    

    players.conf
    を編集:

    PLAYERS=(
      "player1:pass123:player1@example.com:Australian"
      "player2:pass456:player2@example.com:Canadian"
      # … add one line per player
    )
    

    フォーマットは

    "username:password:email:nation"

    このファイルは git‑ignore され、認証情報はローカルに残ります。
    longturn.serv
    start.sh
    aitoggle
    エントリに対応する
    create
    コマンドを追加してください(
    HOWTO-PROVISION-PLAYERS.md
    を参照)。

  4. Fly.io へデプロイ

    fly launch --name your-app-name
    fly volumes create freeciv_saves --size 1 --region your-region
    fly secrets set \
      SES_SMTP_USER=your-ses-smtp-username \
      SES_SMTP_PASS=your-ses-smtp-password \
      OPENAI_API_KEY=your-openai-key
    fly deploy
    
  5. プレイヤーアカウント作成

    ./manage_players.sh create-all    # すべてのアカウント + ウェルカムメール送信
    # 単一プレイヤーの場合:
    ./manage_players.sh create username password email@example.com
    

    SQLite 認証 DB に書き込み、各プレイヤーへ接続手順付きウェルカムメールを送信します。

  6. 接続情報共有
    プレイヤーは Freeciv 3.2.3 クライアントで次の設定を使用して接続します:

    • ホスト:
      your-app-name.fly.dev
    • ポート:
      5556
    • ユーザー名/パスワード:作成時に指定したもの

    ステータスページは

    https://your-app-name.fly.dev
    で確認できます。


よくある操作

# 変更をデプロイ
fly deploy

# コンテナへ SSH
fly ssh console --app your-app-name

# 強制セーブ
fly ssh console --app your-app-name -C "sh -c 'echo save > /tmp/server-input'"

# ステータスページ再生成
fly ssh console --app your-app-name -C "/opt/freeciv/generate_status_json.sh"

# サーバーログ確認
fly ssh console --app your-app-name -C "tail -50 /data/saves/server.log"

# ターン締切を 4 AM に変更
./fix_turn_timer.sh 4

# プレイヤーの金額を変更
./change_gold.sh playername 100

# メール通知をオフにする
# `email_enabled.settings` を "false" に編集し、再デプロイ

# サーバー再起動(タイマーは継続)
fly apps restart your-app-name

ゲーム状態の変更方法

ゲーム中に状態を安全に変更する最も確実な手段はセーブファイルを直接編集することです。
FIFO コマンドは約 200 文字を超えると崩れ、サーバー側で多くのコマンドが途中でブロックされます。

  1. 強制セーブ

    fly ssh console --app your-app-name -C "sh -c 'echo save > /tmp/server-input; sleep 3'"
    
  2. ダウンロード

    fly ssh console --app your-app-name -C "cat /data/saves/save-latest.sav.gz" > /tmp/save.sav.gz
    gzip -dc /tmp/save.sav.gz > /tmp/save.txt
    
  3. /tmp/save.txt
    を編集(プレーンテキスト INI 形式)。

  4. アップロード&再起動

    gzip -c /tmp/save.txt > /tmp/save-edited.sav.gz
    cat /tmp/save-edited.sav.gz | base64 | fly ssh console --app your-app-name \
      -C "sh -c 'base64 -d > /data/saves/save-latest.sav.gz'"
    fly apps restart your-app-name
    

再起動時のレジリエンス

サーバーは再起動やリデプロイ時にターンタイマーを保持します。

start.sh
は:

  • セーブファイルから
    phase_seconds
    (現在のターン経過秒)を読み取ります。
  • 残り時間=
    timeout - phase_seconds
    を計算し、正しい締切を再設定します。
  • プレイヤーがタイムロスしないようにします。

環境変数

変数必須デフォルト説明
SES_SMTP_USER
はいAWS SES SMTP ユーザー名
SES_SMTP_PASS
はいAWS SES SMTP パスワード
SES_SMTP_HOST
いいえ
email-smtp.us-east-1.amazonaws.com
SES SMTP エンドポイント
OPENAI_API_KEY
いいえAI 新聞用 OpenAI API キー
SERVER_HOST
いいえ
freeciv.andrewmcgrath.info
サーバーのホスト名(メール/ステータスページ)
FROM_EMAIL
いいえ
freeciv@andrewmcgrath.info
送信者メールアドレス

本番環境では Fly.io のシークレットとして設定します:

fly secrets set SES_SMTP_USER=... SES_SMTP_PASS=... OPENAI_API_KEY=...

プロジェクト構成

├── Dockerfile                  # マルチステージビルド(Freeciv コンパイル + ランタイム)
├── fly.toml                    # Fly.io 設定
├── entrypoint.sh               # コンテナエントリーポイント
├── start.sh                    # サーバー起動オーケストレーター
├── longturn.serv               # ゲーム設定
├── fcdb.conf                   # 認証 DB 設定
├── database.lua                # DB 初期化
├── crontab                     # スケジュールタスク
├── email_enabled.settings      # メール通知トグル
├── turn_notify.lua             # ターン変更シグナルハンドラ
├── generate_status_json.sh     # ステータスページデータパイプライン
├── generate_gazette.sh         # AI 新聞生成
├── generate_nations.sh         # 国一覧ページ生成
├── turn_notify.sh              # ターン通知メール送信
├── turn_reminder.sh            # 締切リマインダーメール
├── manage_players.sh           # プレイヤーアカウント管理
├── fix_turn_timer.sh           # 手動締切オーバーライド
├── change_gold.sh              # 金額調整ユーティリティ
├── local_preview.sh            # ローカルステータスページプレビュー
├── .env.sample                 # 環境変数テンプレート
└── www/
    ├── index.html              # ステータスページ(JS 測定)
    ├── changelog.html          # ゲーム変更履歴
    └── cgi-bin/
        └── health              # ヘルスチェックエンドポイント

CLAUDE.md – 運用参考資料。

同じ日のほかのニュース

一覧に戻る →

2026/03/19 5:45

再生成された場合、保証は無効となります。

## 日本語訳: > **トム・ハートマンは農業機械の「ソフトウェアメカニック」として自らを再定義しました。** ジョン・ディール社のソフトウェア修理事業が消滅した後、彼は従来のトラブルシューティングから意図された技術動作と実際のパフォーマンス(仕様上の問題)のギャップを診断する方向へシフトしたことを示す新しいサイン「HARTMANN SOFTWARE MECHANICS」を追加しました。 > > 彼の工房では、ハードウェア障害とソフトウェア仕様エラーの両方に対処します。コーヒーマシン実験を通じて、仕様上の欠落がどのように高額な失敗につながるかというドメイン課題を示しています。 > > **クライアント:** > • *マーガレット・ブレナン* – 彼女のキャベツ農場の収穫タイミングツールが天候モデル更新後に成熟度を過小評価したため、トムは仕様に監視条項を追加しました。 > • *イーサン・ノヴァク* – 40種類のカスタムツールを持つ乳製品農家で、「話す」ものがあったが全体的なアーキテクチャが欠如し、飼料ツール再生成後にミルク価格が8 %低下した。トムは「ソフトウェア・チョレオグラファー」(メガン・キャラハン)を提案しました。 > • *キャロル・リンデグレン* – 有機野菜農場で、孫が灌漑最適化ハブを設置。トムは物理的なオーバーライドスイッチとログ記録を提供し、現場固有の知識を保持しました。 > > 共通する問題として「グラウンド・ムーブ」(仕様に捉えられない upstream データ/ソース変更)や「スパゲッティ」(アドホックなツール間インターフェース)が挙げられます。 > > **メトリクス:** 1日あたり6–8件のクライアント、94 % の診断成功率、仕様修正ごとの平均請求額 $180、および継続的な四半期検査。 > > **経済的洞察:** クライアントはしばしば予防保全に抵抗します――失敗よりもコストが低いにもかかわらず―これは人間医療の緊急対応をウェルネスチェックより優先する傾向と似ています。 > > **成果と将来計画:** マーガレットのツールは修復済み、イーサンはチョレオグラフィーを採用予定、キャロルは週に3回オーバーライドスイッチを使用し、トムが四半期ごとに検査を実施します。このアプローチは失敗コストの低減、積極的な保守の奨励、および反応的バグ修正よりも仕様品質を優先する農業技術産業への影響力を高める可能性があります。

2026/03/15 21:20

**オープンロケット**

## Japanese Translation: > **OpenRocket** は、ユーザーがロケットを設計・シミュレーションし、実際に構築する前に最適化できる無料のオープンソースモデルロケットシミュレータです。 > 50以上の変数を備えた最新鋭の六自由度飛行エンジン、リアルタイム性能データ(圧力中心・重心・最大高度・速度・安定性など)、高度なプロット/エクスポート機能を提供します。 > デザイナーは材質密度、仕上げ品質、部品カタログ項目、カスタムパーツを含むCAD風図面を作成し、設計のPDFをエクスポートできます。 > 組み込み AI アシスタントが自動的にパラメータを調整し、高高度などの最適化目標を達成します。 > OpenRocket は ThrustCurve から取得した包括的なデータベースを使用して、マルチステージ・ダブルデプロイメント・クラスターモーター構成をサポートします。 > 本プロジェクトは GitHub を通じて貢献を歓迎し、ユーザーと開発者向けに豊富なドキュメントを提供するとともに、アイデア共有や新機能の議論が行われる活発な Discord コミュニティを維持しています。 > 今後のリリースではプロット/エクスポートツールのさらなる強化、AI 主導の最適化の深化、およびユーザーフィードバックの取り込みを継続します。 この改訂版サマリーはすべての重要ポイントを統合し、非推奨の推論を除外し、あいまいな表現なしに主旨を明確に提示しています。

2026/03/18 16:43

**ワンダー** *小さなウェブを探索するための、ちょっとした分散型ツール*

## 日本語訳: 以下のテキストは「Wander」コンソールのセットアップ方法と使用法について説明しています。 「Wander」は、コミュニティが共有するランダムなウェブサイトを探索できる軽量なWebインターフェースです。 1. **設定手順** - `index.html` と `wander.js` が含まれる ZIP ファイルをダウンロードします。 - これらのファイルを自分のウェブサイトの `/wander/` ディレクトリに展開します。 - `wander.js` を codeberg.org/susam/wander の指示に従って編集します。 - `/wander/` フォルダがオンラインになったら、コミュニティスレッドで自分のコンソールへのリンクを共有します。 2. **動作原理** - 別サイトの Wander コンソールを訪れると、現在のウェブサイトのコンソールからその別サイトのコンソールへ移動します。 - 元のコンソールは他のコンソールから再帰的におすすめを取得できるため、ネットワーク閲覧時にコンソールを変更する必要はありません。 3. **コミュニティの背景** - Wander コミュニティは、自分自身の個人ウェブサイトを開発・運営している人々で構成されています。 - 自分のコンソールを他者のリストに追加することで、Wander ネットワークへの参加が促進されます。 4. **追加情報** - 詳細は codeberg.org/susam/wander をご覧ください。 --- この改訂版要約は、主要なポイントをすべて反映し、根拠のない利益を加えずに主旨を明確かつ簡潔に示しています。