異世界転生したら魔法がAPIだった件   作:nelldrip

3 / 6
この「2.5話」は、本編とは少し毛色が違います。いわば「おまけ」であり、「設定資料集」であり、「異世界の魔法書」です。

本編第2話で、健一がスキル『マジック・アーキテクト』を起動した瞬間——彼の視界に広がったのは、TypeScriptで書かれた魔法の構造と、Rustで書かれた物理エンジンでした。

この章では、それを「そのまま」お見せします。

プログラミングに詳しい読者は「おおっ!」となり、詳しくない読者は「なんかすごいものが書いてある」と雰囲気を楽しんでください。どちらでも構いません。

なぜなら、これは——「神様が書いた、世界の設計書」だからです。

そう、あのポテチを食べながらコーラを飲む女神が、MITライセンスで世界を公開しているのです。無保証です。自己責任でお願いします。

——作者


第2.5話 10歳、APIを叩く(魔法機序編)

---

TypeScript 魔法型宣言

---

// ============================================================

// 1. 基本型定義

// ============================================================

 

type Mana = number; // 魔力値(MP)

type LearnPoint = number;

 

type PhysicsModel =

| "thermodynamics"

| "projectileMotion"

| "fluidDynamics"

| "standardModel"

| "quantumFieldTheory"

| "molecularBonding"

| "nanotechnology"

| "bioelectrochemistry"

| "quantumElectrodynamics"

| "extendedPhysics"; // 魔法による拡張物理

 

type ControlParameter = {

name: string;

unit?: string;

range?: { min: number; max: number };

};

 

// ============================================================

// 2. 魔法メカニズムの構成要素

// ============================================================

 

interface MagicComponent {

phase: string; // フェーズ名(例: "formation", "impact")

operation: string; // 操作名(例: "thermalEnergyGeneration")

description: string; // 詳細説明

}

 

interface MagicMechanism {

type: string; // 魔法のカテゴリ(例: "energyProjectile", "matterSynthesis")

components: MagicComponent[];

physicsModel: PhysicsModel | PhysicsModel[];

controlParameters: ControlParameter[];

constraints?: Record<string, any>; // 追加制約

}

 

// ============================================================

// 3. 魔法のコスト構造

// ============================================================

 

interface MagicCost {

learnPoints: LearnPoint;

manaConsumption: {

min: Mana;

max: Mana;

unit: "MP";

};

}

 

// ============================================================

// 4. 魔法エンティティ

// ============================================================

 

interface Spell {

id: string;

name: string;

nameJa: string;

cost: MagicCost;

mechanism: MagicMechanism;

}

 

// ============================================================

// 5. 魔法定義

// ============================================================

 

const fireball: Spell = {

id: "fireball",

name: "Fireball",

nameJa: "ファイアボール",

cost: {

learnPoints: 20,

manaConsumption: { min: 10, max: 30, unit: "MP" }

},

mechanism: {

type: "energyProjectile",

components: [

{

phase: "formation",

operation: "thermalEnergyGeneration",

description: "熱エネルギーを生成・集束する"

},

{

phase: "launch",

operation: "projectilePropulsion",

description: "投射体として対象に向けて射出する"

},

{

phase: "impact",

operation: "diffusionControlOnCollision",

description: "衝突時に拡散を制御し、爆発範囲と威力を調整する"

}

],

physicsModel: ["thermodynamics", "projectileMotion", "fluidDynamics"],

controlParameters: [

{ name: "初速", unit: "m/s" },

{ name: "熱量(温度)", unit: "K" },

{ name: "拡散角度", unit: "deg" },

{ name: "有効半径", unit: "m" }

]

}

};

 

const aquaCreate: Spell = {

id: "aqua_create",

name: "Aqua Create",

nameJa: "アクア・クリエイト",

cost: {

learnPoints: 3,

manaConsumption: { min: 5, max: 50, unit: "MP" }

},

mechanism: {

type: "matterSynthesis",

components: [

{

phase: "synthesis",

operation: "standardModelHydrogenOxygenBonding",

description: "標準模型に基づき、水素原子と酸素原子を結合させて水分子を形成する"

}

],

physicsModel: ["standardModel", "quantumFieldTheory", "molecularBonding"],

controlParameters: [

{ name: "生成量", unit: "mol" },

{ name: "生成速度", unit: "mol/s" },

{ name: "生成位置", unit: "m" }

],

constraints: {

requiresElements: ["水素", "酸素"],

source: "周囲環境からの元素収集、または魔力から直接生成"

}

}

};

 

const heal: Spell = {

id: "heal",

name: "Heal",

nameJa: "ヒール",

cost: {

learnPoints: 30,

manaConsumption: { min: 15, max: 200, unit: "MP" }

},

mechanism: {

type: "biologicalRestoration",

components: [

{

phase: "diagnosis",

operation: "nanoOperation",

description: "ナノスケールで生体組織を走査し、損傷部位を特定する"

},

{

phase: "preparation",

operation: "ionOperation",

description: "イオンバランスを操作し、細胞内外の電位差やpHを修復環境に整える"

},

{

phase: "synthesis",

operation: "standardModelArbitraryElementMolecularFormation",

description: "標準模型に基づき、任意の元素から必要な分子を構造形成する"

},

{

phase: "activation",

operation: "chargeGeneration",

description: "電荷を発生させて生体電気信号を補助し、組織再生を促進する"

}

],

physicsModel: [

"nanotechnology",

"bioelectrochemistry",

"standardModel",

"quantumElectrodynamics"

],

controlParameters: [

{ name: "治癒対象部位" },

{ name: "再生速度" },

{ name: "合成する分子種と量" },

{ name: "電荷強度と周波数", unit: "Hz" }

],

constraints: {

requiresBiocompatibility: true,

riskFactors: [

"過剰再生(腫瘍化リスク)",

"イオンバランス崩壊",

"電荷過剰による神経障害"

]

}

}

};

 

// ============================================================

// 6. システム全体管理

// ============================================================

 

interface MagicSystem {

spells: Spell[];

commonRules: {

manaConsumption: string;

learnPoints: string;

physicsBasis: string;

};

}

 

const magicSystem: MagicSystem = {

spells: [fireball, aquaCreate, heal],

commonRules: {

manaConsumption: "消費魔力は、制御パラメータの複雑性・精度・対象規模に応じて増加する",

learnPoints: "習得には累積的な訓練と理解度が必要",

physicsBasis: "全ての魔法は標準模型および古典物理学を拡張した形で作用する"

}

};

 

// ============================================================

// 7. 実行時処理の例(関数)

// ============================================================

 

function castSpell(spell: Spell, manaPool: Mana, params: Record<string, any>): { success: boolean; remainingMana: Mana; effect?: string } {

// 魔力チェック

const requiredMana = spell.cost.manaConsumption.min; // 実際はパラメータに応じて変動

if (manaPool < requiredMana) {

return { success: false, remainingMana: manaPool };

}

 

// 各コンポーネントを順次実行(擬似処理)

for (const component of spell.mechanism.components) {

console.log(`[${spell.nameJa}] ${component.phase}: ${component.description}`);

// ここで実際の物理・魔法処理が走る

}

 

const remainingMana = manaPool - requiredMana;

return {

success: true,

remainingMana,

effect: `${spell.nameJa} を発動しました(パラメータ: ${JSON.stringify(params)})`

};

}

 

// ============================================================

// 8. 使用例

// ============================================================

 

const result = castSpell(fireball, 100, { temperature: 3000, radius: 5 });

console.log(result);

 

---

 

 

 

---

RUST構文 魔法低レベル層

---

use std::collections::HashMap;

use std::fmt;

use std::sync::Arc;

use std::time::{SystemTime, UNIX_EPOCH};

 

// ============================================================

// 1. 基本型・列挙型定義

// ============================================================

 

/// 素粒子情報

#[derive(Debug, Clone, PartialEq)]

pub struct SubatomicParticle {

pub proton_count: i32,

pub neutron_count: i32,

pub charge: i32, // 素電荷単位(-1, 0, +1 など)

}

 

impl SubatomicParticle {

pub fn mass_number(&self) -> i32 {

self.proton_count + self.neutron_count

}

 

```

pub fn is_stable(&self) -> bool {

// 簡易的な安定性判定

self.neutron_count >= (self.proton_count as f64 * 0.8) as i32

}

```

 

}

 

/// 3次元ベクトル

#[derive(Debug, Clone, Copy, PartialEq)]

pub struct Vector3 {

pub x: f64,

pub y: f64,

pub z: f64,

}

 

impl Vector3 {

pub fn new(x: f64, y: f64, z: f64) -> Self {

Self { x, y, z }

}

 

```

pub fn zero() -> Self {

Self::new(0.0, 0.0, 0.0)

}

 

pub fn distance(&self, other: &Vector3) -> f64 {

let dx = self.x - other.x;

let dy = self.y - other.y;

let dz = self.z - other.z;

(dx * dx + dy * dy + dz * dz).sqrt()

}

```

 

}

 

impl fmt::Display for Vector3 {

fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {

write!(f, "({:.2}, {:.2}, {:.2})", self.x, self.y, self.z)

}

}

 

/// 物質情報

#[derive(Debug, Clone)]

pub struct Matter {

pub id: String,

pub name: String,

pub composition: SubatomicParticle,

pub amount: f64, // モル数

pub position: Vector3,

pub velocity: Vector3,

pub mass: f64, // グラム単位

}

 

impl Matter {

pub fn new(name: String, composition: SubatomicParticle, amount: f64, position: Vector3) -> Self {

let mass = Self::calculate_mass(&composition, amount);

Self {

id: Self::generate_id(),

name,

composition,

amount,

position,

velocity: Vector3::zero(),

mass,

}

}

 

```

fn calculate_mass(composition: &SubatomicParticle, amount: f64) -> f64 {

// 原子量 = 陽子数 + 中性子数(近似)

let atomic_mass = (composition.proton_count + composition.neutron_count) as f64;

atomic_mass * amount * 1.66054e-24 // グラム換算(簡易)

}

 

fn generate_id() -> String {

let timestamp = SystemTime::now()

.duration_since(UNIX_EPOCH)

.unwrap()

.as_nanos();

format!("matter_{}", timestamp)

}

```

 

}

 

/// エネルギー種別

#[derive(Debug, Clone, Copy, PartialEq, Eq)]

pub enum EnergyType {

Thermal, // 熱エネルギー

Kinetic, // 運動エネルギー

Electrical, // 電気エネルギー

Radiant, // 放射エネルギー

Magical, // 魔力エネルギー

Potential, // 位置エネルギー

}

 

impl fmt::Display for EnergyType {

fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {

match self {

EnergyType::Thermal => write!(f, "熱"),

EnergyType::Kinetic => write!(f, "運動"),

EnergyType::Electrical => write!(f, "電気"),

EnergyType::Radiant => write!(f, "放射"),

EnergyType::Magical => write!(f, "魔力"),

EnergyType::Potential => write!(f, "位置"),

}

}

}

 

/// エネルギー情報

#[derive(Debug, Clone)]

pub struct Energy {

pub id: String,

pub energy_type: EnergyType,

pub amount: f64, // ジュール単位

pub position: Option<Vector3>,

}

 

impl Energy {

pub fn new(energy_type: EnergyType, amount: f64, position: Option<Vector3>) -> Self {

Self {

id: Self::generate_id(),

energy_type,

amount,

position,

}

}

 

```

fn generate_id() -> String {

let timestamp = SystemTime::now()

.duration_since(UNIX_EPOCH)

.unwrap()

.as_nanos();

format!("energy_{}", timestamp)

}

```

 

}

 

/// 魔法実行結果

#[derive(Debug, Clone)]

pub enum MagicResult<T> {

Success {

message: String,

data: Option<T>,

mana_cost: f64,

},

Failure {

message: String,

mana_cost: f64,

},

}

 

impl<T> MagicResult<T> {

pub fn is_success(&self) -> bool {

matches!(self, MagicResult::Success { .. })

}

 

```

pub fn is_failure(&self) -> bool {

matches!(self, MagicResult::Failure { .. })

}

 

pub fn message(&self) -> &str {

match self {

MagicResult::Success { message, .. } => message,

MagicResult::Failure { message, .. } => message,

}

}

```

 

}

 

// ============================================================

// 2. コアな魔法関数群

// ============================================================

 

pub struct MagicFunctions {

matter_registry: HashMap<String, Matter>,

energy_registry: Vec<Energy>,

mana_pool: f64,

total_mana_consumed: f64,

}

 

impl MagicFunctions {

pub fn new(initial_mana: f64) -> Self {

Self {

matter_registry: HashMap::new(),

energy_registry: Vec::new(),

mana_pool: initial_mana,

total_mana_consumed: 0.0,

}

}

 

```

pub fn mana_pool(&self) -> f64 {

self.mana_pool

}

 

pub fn total_mana_consumed(&self) -> f64 {

self.total_mana_consumed

}

 

// ============================================================

// 2-1. 物質生成関数

// ============================================================

 

/// 物質生成関数:陽子数、電荷、中性子数、量を指定して物質を生成

pub fn generate_matter(

&mut self,

proton_count: i32,

charge: i32,

neutron_count: i32,

amount: f64,

position: Vector3,

matter_name: Option<String>,

) -> MagicResult<String> {

// 魔力消費計算

let base_cost = 5.0e-8;

let complexity_cost = (proton_count + neutron_count) as f64 * 0.5e-5;

let amount_cost = amount * 2.0e-5;

let total_cost = base_cost + complexity_cost + amount_cost;

 

if self.mana_pool < total_cost {

return MagicResult::Failure {

message: format!("魔力不足: 必要 {:.2}MP / 現在 {:.2}MP", total_cost, self.mana_pool),

mana_cost: total_cost,

};

}

 

// 素粒子構成を検証

let particle = SubatomicParticle {

proton_count,

neutron_count,

charge,

};

 

// 元素名を生成

let name = matter_name.unwrap_or_else(|| Self::generate_element_name(proton_count));

 

// 物質生成

let matter = Matter::new(name.clone(), particle, amount, position);

let matter_id = matter.id.clone();

 

// レジストリに登録

self.matter_registry.insert(matter_id.clone(), matter);

 

// 魔力消費

self.mana_pool -= total_cost;

self.total_mana_consumed += total_cost;

 

MagicResult::Success {

message: format!("{}を {:.2}モル生成しました(位置: {})", name, amount, position),

data: Some(matter_id.clone()),

mana_cost: total_cost,

}

}

 

fn generate_element_name(proton_count: i32) -> String {

match proton_count {

1 => "水素".to_string(),

2 => "ヘリウム".to_string(),

6 => "炭素".to_string(),

7 => "窒素".to_string(),

8 => "酸素".to_string(),

11 => "ナトリウム".to_string(),

26 => "鉄".to_string(),

29 => "銅".to_string(),

79 => "金".to_string(),

_ => format!("元素{}", proton_count),

}

}

 

// ============================================================

// 2-2. 位置制御関数

// ============================================================

 

/// 位置制御関数:対象を指定座標に移動

pub fn control_position(

&mut self,

target_id: &str,

target_position: Vector3,

) -> MagicResult<Vector3> {

let matter = match self.matter_registry.get_mut(target_id) {

Some(m) => m,

None => {

return MagicResult::Failure {

message: format!("対象物質が見つかりません: {}", target_id),

mana_cost: 0.0,

}

}

};

 

// 移動距離に応じた魔力消費

let distance = matter.position.distance(&target_position);

let base_cost = 1.0;

let distance_cost = distance * 0.1;

let mass_cost = matter.mass * 0.01;

let total_cost = base_cost + distance_cost + mass_cost;

 

if self.mana_pool < total_cost {

return MagicResult::Failure {

message: format!("魔力不足: 必要 {:.2}MP / 現在 {:.2}MP", total_cost, self.mana_pool),

mana_cost: total_cost,

};

}

 

// 位置変更

let old_position = matter.position;

matter.position = target_position;

 

self.mana_pool -= total_cost;

self.total_mana_consumed += total_cost;

 

MagicResult::Success {

message: format!("{}を {} から {} に移動しました", matter.name, old_position, target_position),

data: Some(old_position),

mana_cost: total_cost,

}

}

 

// ============================================================

// 2-3. 運動制御関数

// ============================================================

 

/// 運動制御関数:対象に速度ベクトルを与える

pub fn control_motion(

&mut self,

target_id: &str,

velocity: Vector3,

) -> MagicResult<Vector3> {

let matter = match self.matter_registry.get_mut(target_id) {

Some(m) => m,

None => {

return MagicResult::Failure {

message: format!("対象物質が見つかりません: {}", target_id),

mana_cost: 0.0,

}

}

};

 

// 速度変化量に応じた魔力消費

let speed_change = matter.velocity.distance(&velocity);

let base_cost = 1.0;

let kinetic_cost = speed_change * matter.mass * 0.5;

let total_cost = base_cost + kinetic_cost;

 

if self.mana_pool < total_cost {

return MagicResult::Failure {

message: format!("魔力不足: 必要 {:.2}MP / 現在 {:.2}MP", total_cost, self.mana_pool),

mana_cost: total_cost,

};

}

 

// 速度変更

let old_velocity = matter.velocity;

matter.velocity = velocity;

 

self.mana_pool -= total_cost;

self.total_mana_consumed += total_cost;

 

MagicResult::Success {

message: format!("{}の速度を {} から {} に変更しました", matter.name, old_velocity, velocity),

data: Some(old_velocity),

mana_cost: total_cost,

}

}

 

// ============================================================

// 2-4. エネルギー変換関数

// ============================================================

 

/// エネルギー変換関数:指定種類・量のエネルギーを発生

pub fn generate_energy(

&mut self,

energy_type: EnergyType,

amount: f64,

position: Option<Vector3>,

) -> MagicResult<Energy> {

// エネルギー種別に応じた魔力消費係数

let coefficient = match energy_type {

EnergyType::Thermal => 0.8 * 200.0,

EnergyType::Kinetic => 1.0 * 200.0,

EnergyType::Electrical => 1.2 * 200.0,

EnergyType::Radiant => 1.5 * 200.0,

EnergyType::Magical => 2.0 * 200.0,

EnergyType::Potential => 0.9 * 200.0,

};

 

let total_cost = amount * coefficient * 0.1;

 

if self.mana_pool < total_cost {

return MagicResult::Failure {

message: format!("魔力不足: 必要 {:.2}MP / 現在 {:.2}MP", total_cost, self.mana_pool),

mana_cost: total_cost,

};

}

 

// エネルギー生成

let energy = Energy::new(energy_type, amount, position);

let energy_clone = energy.clone();

self.energy_registry.push(energy);

 

self.mana_pool -= total_cost;

self.total_mana_consumed += total_cost;

 

let pos_str = match position {

Some(p) => format!(" (位置: {})", p),

None => String::new(),

};

 

MagicResult::Success {

message: format!("{}エネルギーを {:.2}J 発生しました{}", energy_type, amount, pos_str),

data: Some(energy_clone),

mana_cost: total_cost,

}

}

 

// ============================================================

// 3. ユーティリティ関数

// ============================================================

 

/// 登録されている物質をすべて取得

pub fn get_all_matter(&self) -> &HashMap<String, Matter> {

&self.matter_registry

}

 

/// 登録されているエネルギーをすべて取得

pub fn get_all_energy(&self) -> &Vec<Energy> {

&self.energy_registry

}

 

/// システムリセット

pub fn reset(&mut self) {

self.matter_registry.clear();

self.energy_registry.clear();

self.total_mana_consumed = 0.0;

}

 

/// 魔力を補充

pub fn add_mana(&mut self, amount: f64) {

self.mana_pool += amount;

}

```

 

}

 

// ============================================================

// 4. 使用例

// ============================================================

 

fn main() {

let mut magic = MagicFunctions::new(5000.0);

 

```

// 1. 物質生成(酸素)

let result1 = magic.generate_matter(

8, // 陽子数

0, // 電荷

8, // 中性子数

2.5, // モル数

Vector3::new(10.0, 5.0, 0.0),

Some("酸素".to_string()),

);

 

match result1 {

MagicResult::Success { message, data, mana_cost } => {

println!("{} (消費MP: {:.2})", message, mana_cost);

 

if let Some(matter_id) = data {

// 2. 位置制御

let result2 = magic.control_position(

&matter_id,

Vector3::new(15.0, 10.0, 0.0),

);

match result2 {

MagicResult::Success { message, .. } => println!("{}", message),

MagicResult::Failure { message, .. } => println!("エラー: {}", message),

}

 

// 3. 運動制御

let result3 = magic.control_motion(

&matter_id,

Vector3::new(5.0, 0.0, 0.0),

);

match result3 {

MagicResult::Success { message, .. } => println!("{}", message),

MagicResult::Failure { message, .. } => println!("エラー: {}", message),

}

}

}

MagicResult::Failure { message, .. } => {

println!("エラー: {}", message);

}

}

 

// 4. エネルギー生成

let result4 = magic.generate_energy(

EnergyType::Thermal,

1000.0,

Some(Vector3::new(10.0, 5.0, 0.0)),

);

match result4 {

MagicResult::Success { message, mana_cost, .. } => {

println!("{} (消費MP: {:.2})", message, mana_cost);

}

MagicResult::Failure { message, .. } => {

println!("エラー: {}", message);

}

}

 

println!("\n消費魔力合計: {:.2} MP", magic.total_mana_consumed());

println!("残り魔力: {:.2} MP", magic.mana_pool());

```

 

}

 

---

 

 

 

---

ライセンスポリシー

---

 

// Copyright (c) 2026 神さま

//

// Permission is hereby granted, free of charge, to any person obtaining a copy

// of this software and associated documentation files (the "Software"), to deal

// in the Software without restriction, including without limitation the rights

// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell

// copies of the Software, and to permit persons to whom the Software is

// furnished to do so, subject to the following conditions:

//

// The above copyright notice and this permission notice shall be included in all

// copies or substantial portions of the Software.

//

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE

// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE

// SOFTWARE.

 

---




いかがだっただろうか。

正直に言うと、このコードを書いているとき、テンションMAXである。だって、魔法がTypeScriptの型定義で表現されているんですよ? ファイアボールがインターフェースになってるんですよ? ヒールのリスク要因に「腫瘍化リスク」が書いてあるんですよ?

特にヒールの実装は、本気で考えてます。「ナノスケールで生体組織を走査」→「イオンバランスを操作」→「標準模型に基づき任意の分子を形成」→「電荷を発生させて再生促進」——これ、医療技術の未来像そのものです。異世界の治癒魔法が、実は超高度なナノ医療だったという設定、地味に気に入っています。

そしてRustの低レベル層。物質生成が異常に安いという設定を、コードのコスト計算で明確に示しています。base_cost = 5.0e-8 vs coefficient = 0.8 * 200.0。この差が、すべての元凶です。

そう、健一が「物質生成はタダ同然で、エネルギー変換はバカ高い」と気づいたのは、このコードを読んだからなんですよ。

ちなみに——ライセンスポリシーの「Copyright (c) 2026 神さま」、書いてて本気で笑いました。
神様がMITライセンスを選んだ理由は「無保証(AS IS)の一文が一番短くて済むから」です。
BSDだと保証否認が長いので、コピペの手間を省きたかったんですね。
ズボラにもほどがある。

エンジニアの皆さんへ。このコード、実際には動きません。当たり前です。
神様の実装はもっと複雑で、もっとバグが多くて、もっと「まあいいや」で動いてるはずです。だってあの女神ですから。

それでも——もし「魔法ってこういう風に実装されてたら面白いな」と思ってもらえたなら、作者としては大成功です。

次回、本編に戻ります。健一が「APIを叩く」その時——神様がポテチを落とす、あの瞬間まで、もう少しだけお待ちください。

——作者
  1. 目次
  2. 小説情報
  3. 縦書き
  4. しおりを挟む
  5. お気に入り登録
  6. 評価
  7. 感想
  8. ここすき
  9. 誤字
  10. 閲覧設定

▲ページの一番上に飛ぶ
X(Twitter)で読了報告
感想を書く ※感想一覧 ※ログインせずに感想を書き込みたい場合はこちら
内容
0文字 10~5000文字
感想を書き込む前に 感想を投稿する際のガイドライン に違反していないか確認して下さい。
※展開予想はネタ潰しになるだけですので、感想欄ではご遠慮ください。