吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 960|回复: 20
上一主题 下一主题
收起左侧

[Python 转载] 将一本小说转为一个html版的MUD游戏:Story2MUD

[复制链接]
跳转到指定楼层
楼主
top7777 发表于 2026-6-26 14:32 回帖奖励
本帖最后由 top7777 于 2026-6-26 14:36 编辑

Story2MUD:将小说文本自动转换为HTML版MUD文字冒险游戏的工具。
     该项目结合了本地NLP处理(jieba分词)和AI生成(DeepSeek API),通过四阶段流程高效转换小说为互动游戏。架构清晰,包含模板管理、缓存机制和Token优化,适合处理大文本。适用于小说爱好者、游戏开发者快速生成复古风格文字冒险游戏,但现有测试覆盖不足,可维护性也有待提升,请高手继续改进。
自带了一个“非典型道士”转的“豆兵记”测试章MUD。

Story2MUD

将小说文本转换为HTML版MUD文字冒险游戏。

GitHub: https://github.com/TOP777/story2MUD

功能

  • 导入TXT小说文件,支持113万字+大文件
  • 四阶段转换流程,逐步构建游戏
  • 支持多种小说类别(仙侠/玄幻/武侠/悬疑/科幻/通用)
  • 模板可复用:保存/加载自定义模板
  • Token管理:自动压缩、分段,防止API超限
  • 阶段结果缓存:相同文本不重复调用API
  • 调用DeepSeek API生成互动式MUD分支结构
  • 生成单文件HTML游戏,复古终端风格(黑底绿字、CRT扫描线、打字机效果)
  • HTML自动保存到 output/ 目录
  • API Key本地保存/加载
  • 完整日志记录(logs/ 目录)

快速开始

双击 run.bat,自动创建venv、安装依赖、启动程序。

或手动运行:

pip install -r requirements.txt
python main.py

使用步骤

  1. 点击 导入TXT文件 加载小说
  2. 输入 DeepSeek API Key,点击 保存Key 可持久化
  3. 选择小说类别、设置游戏标题和分支密度
  4. (可选)点击 保存模板 将当前类别配置保存为可复用模板
  5. 点击 开始转换,等待四阶段处理完成
  6. 完成后HTML自动保存到 output/{游戏标题}.html
  7. 点击 浏览器预览 直接打开游戏

四阶段转换流程

导入小说 → [阶段1]模板生成 → [阶段2]粗筛提取 → [阶段3]AI精滤 → [阶段4]AI生成HTML

阶段1:模板生成(本地,无AI调用)

根据选择的小说类别,生成对应的MUD模板,定义典型房间、NPC、物品、事件类型和任务推进模式。

阶段2:粗筛提取(本地NLP)

用jieba分词+正则从原文提取候选要素:

  • 人物(人名、称谓)
  • 地点(场景名、地名后缀词)
  • 物品(武器、道具、秘籍)
  • 事件(动宾结构)

阶段3:AI精滤(1次API调用)

将模板+候选要素发给DeepSeek AI,根据游戏性需求(玩家体验、难度曲线、探索乐趣)决定取舍、合并、拆分,输出精炼的游戏结构(rooms/NPCs/items/quest_chain)。

阶段4:AI生成HTML(按房间数分批调用API)

将精炼后的游戏结构发给AI,生成具体的互动场景和选择分支,组装为HTML。房间较多时自动分批调用,避免token超限。

模板管理

阶段1生成的模板可复用:

  • 保存模板:将当前类别配置保存为自定义模板,存放在 templates/custom/ 目录
  • 加载模板:下次使用时从类别下拉框选择已保存的自定义模板
  • 删除模板:删除不需要的自定义模板(内置模板不可删除)

自定义模板为JSON文件,可手动编辑调整。

缓存机制

阶段2-4的结果会自动缓存(基于文本内容+配置的MD5 hash):

  • 相同文本、相同类别/标题配置 → 直接使用缓存,跳过API调用
  • 界面右下角 清空缓存 按钮可手动清除
  • 缓存文件存放在 cache/ 目录

项目结构

story2MUD/
├── main.py                      # 入口
├── run.bat                      # 一键启动(自动创建venv)
├── requirements.txt             # 依赖列表
├── .gitignore                   # Git忽略清单
├── config.json                  # 运行时配置(自动生成)
├── core/
│   ├── ai_client.py             # DeepSeek API客户端
│   ├── token_manager.py         # Token估算、压缩、分段管理
│   ├── cache_manager.py         # 阶段结果缓存管理
│   ├── story_parser.py          # 小说文本解析
│   ├── template_generator.py    # 阶段1:类别模板生成+保存/加载
│   ├── entity_extractor.py      # 阶段2:实体粗筛提取
│   ├── mud_generator.py         # 阶段3+4:AI精滤与HTML生成
│   └── logger.py                # 日志模块
├── templates/
│   ├── mud_template.html        # HTML模板
│   └── custom/                  # 自定义模板存放目录
├── ui/
│   └── app.py                   # ttk主界面
├── cache/                       # 阶段结果缓存(自动生成)
├── logs/                        # 运行日志(自动生成)
└── output/                      # 生成的HTML游戏(自动生成)

HTML游戏特性

  • 复古终端风格,CRT扫描线动画
  • 场景描述逐字显示(点击跳过)
  • 数字键快速选择分支
  • 场景计数与历史记录
  • 结局与重新开始




1、关键代码:
[Python] 纯文本查看 复制代码
import tkinter as tk
from tkinter import ttk, filedialog, messagebox, simpledialog
import threading
import os
import sys
import json
from typing import Dict, List

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from core.story_parser import parse_story_file, split_into_chapters
from core.template_generator import generate_template, get_genre_list, save_template, load_template, delete_template
from core.entity_extractor import extract_entities, format_extraction_result
from core.ai_client import DeepSeekClient
from core.mud_generator import refine_with_ai, generate_scenes_from_structure, build_html
from core.cache_manager import get_cached, set_cached, clear_cache, get_cache_size
from core.logger import get_logger

log = get_logger("app")

CONFIG_PATH = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "config.json")


class Story2MUDApp:
    def __init__(self, root):
        self.root = root
        self.root.title("Story2MUD - 小说转MUD游戏工具")
        self.root.geometry("750x700")
        self.root.resizable(True, True)

        self.story_text = ""
        self.html_output = ""
        self.last_output_path = ""
        self.converting = False

        self._build_ui()
        self._load_config()

    def _build_ui(self):
        main = ttk.Frame(self.root, padding=15)
        main.pack(fill=tk.BOTH, expand=True)

        # Title
        ttk.Label(main, text="Story2MUD", font=("Helvetica", 16, "bold")).pack(anchor=tk.W)
        ttk.Label(main, text="将小说文本转换为MUD文字冒险游戏(四阶段流程)", foreground="gray").pack(anchor=tk.W)
        ttk.Separator(main, orient=tk.HORIZONTAL).pack(fill=tk.X, pady=10)

        # File import
        file_frame = ttk.LabelFrame(main, text="小说文件", padding=8)
        file_frame.pack(fill=tk.X, pady=(0, 10))

        file_btn_frame = ttk.Frame(file_frame)
        file_btn_frame.pack(fill=tk.X)

        ttk.Button(file_btn_frame, text="导入TXT文件", command=self._import_file).pack(side=tk.LEFT)
        self.file_label = ttk.Label(file_btn_frame, text="未选择文件", foreground="gray")
        self.file_label.pack(side=tk.LEFT, padx=10)

        self.preview = tk.Text(file_frame, height=6, wrap=tk.WORD, state=tk.DISABLED,
                               font=("Consolas", 9), bg="#f5f5f5")
        self.preview.pack(fill=tk.X, pady=(8, 0))

        scrollbar = ttk.Scrollbar(self.preview, command=self.preview.yview)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.preview.config(yscrollcommand=scrollbar.set)

        # Config
        config_frame = ttk.LabelFrame(main, text="配置", padding=8)
        config_frame.pack(fill=tk.X, pady=(0, 10))

        # API Key
        api_frame = ttk.Frame(config_frame)
        api_frame.pack(fill=tk.X, pady=2)
        ttk.Label(api_frame, text="DeepSeek API Key:", width=16).pack(side=tk.LEFT)
        self.api_key_var = tk.StringVar()
        self.api_entry = ttk.Entry(api_frame, textvariable=self.api_key_var, show="*", width=35)
        self.api_entry.pack(side=tk.LEFT, fill=tk.X, expand=True)
        ttk.Button(api_frame, text="保存Key", command=self._save_config).pack(side=tk.LEFT, padx=(5, 0))

        # Title
        title_frame = ttk.Frame(config_frame)
        title_frame.pack(fill=tk.X, pady=2)
        ttk.Label(title_frame, text="游戏标题:", width=16).pack(side=tk.LEFT)
        self.title_var = tk.StringVar(value="文字冒险")
        ttk.Entry(title_frame, textvariable=self.title_var, width=45).pack(side=tk.LEFT, fill=tk.X, expand=True)

        # Genre + Density row
        row_frame = ttk.Frame(config_frame)
        row_frame.pack(fill=tk.X, pady=2)

        ttk.Label(row_frame, text="小说类别:", width=16).pack(side=tk.LEFT)
        self.genre_var = tk.StringVar(value="通用")
        self.genre_combo = ttk.Combobox(row_frame, textvariable=self.genre_var, state="readonly", width=10)
        self.genre_combo["values"] = get_genre_list()
        self.genre_combo.pack(side=tk.LEFT)
        self.genre_combo.bind("<<ComboboxSelected>>", self._on_genre_change)

        ttk.Button(row_frame, text="保存模板", command=self._save_template).pack(side=tk.LEFT, padx=(5, 0))
        ttk.Button(row_frame, text="删除模板", command=self._delete_template).pack(side=tk.LEFT, padx=(3, 0))

        ttk.Label(row_frame, text="  分支密度:").pack(side=tk.LEFT)
        self.density_var = tk.StringVar(value="medium")
        density_combo = ttk.Combobox(row_frame, textvariable=self.density_var, state="readonly", width=8)
        density_combo["values"] = ["low", "medium", "high"]
        density_combo.pack(side=tk.LEFT)

        ttk.Label(row_frame, text="(类别影响模板,密度影响分支数量)", foreground="gray").pack(side=tk.LEFT, padx=8)

        # Convert button & progress
        action_frame = ttk.Frame(main)
        action_frame.pack(fill=tk.X, pady=(0, 5))

        self.convert_btn = ttk.Button(action_frame, text="开始转换", command=self._start_convert)
        self.convert_btn.pack(side=tk.LEFT)

        self.progress_var = tk.DoubleVar()
        self.progress_bar = ttk.Progressbar(action_frame, variable=self.progress_var,
                                            maximum=100, length=300)
        self.progress_bar.pack(side=tk.LEFT, padx=10, fill=tk.X, expand=True)

        # Stage labels
        stage_frame = ttk.Frame(main)
        stage_frame.pack(fill=tk.X, pady=(0, 10))

        self.stage_labels = []
        stages = ["①模板", "②粗筛", "③精滤", "④生成"]
        for i, stage in enumerate(stages):
            lbl = ttk.Label(stage_frame, text=stage, foreground="gray", font=("Helvetica", 9))
            lbl.pack(side=tk.LEFT, padx=(0, 15))
            self.stage_labels.append(lbl)

        self.status_label = ttk.Label(stage_frame, text="就绪", foreground="gray")
        self.status_label.pack(side=tk.RIGHT)

        # Output buttons
        output_frame = ttk.Frame(main)
        output_frame.pack(fill=tk.X)

        self.preview_btn = ttk.Button(output_frame, text="浏览器预览", command=self._preview_html, state=tk.DISABLED)
        self.preview_btn.pack(side=tk.LEFT)

        self.save_btn = ttk.Button(output_frame, text="保存HTML", command=self._save_html, state=tk.DISABLED)
        self.save_btn.pack(side=tk.LEFT, padx=10)

        ttk.Button(output_frame, text="清空缓存", command=self._clear_cache).pack(side=tk.RIGHT)

    def _import_file(self):
        filetypes = [("文本文件", "*.txt"), ("所有文件", "*.*")]
        path = filedialog.askopenfilename(filetypes=filetypes)
        if not path:
            return

        try:
            self.story_text = parse_story_file(path)
            self.file_label.config(text=os.path.basename(path))

            self.preview.config(state=tk.NORMAL)
            self.preview.delete("1.0", tk.END)
            self.preview.insert("1.0", self.story_text[:5000])
            if len(self.story_text) > 5000:
                self.preview.insert(tk.END, f"\n\n... (共 {len(self.story_text)} 字)")
            self.preview.config(state=tk.DISABLED)
        except Exception as e:
            messagebox.showerror("错误", f"读取文件失败: {e}")

    def _set_stage(self, index, active):
        color = "#00aa00" if active else "gray"
        font = ("Helvetica", 9, "bold") if active else ("Helvetica", 9)
        self.stage_labels[index].config(foreground=color, font=font)

    def _start_convert(self):
        if self.converting:
            return

        if not self.story_text:
            messagebox.showwarning("提示", "请先导入小说文件")
            return

        api_key = self.api_key_var.get().strip()
        if not api_key:
            messagebox.showwarning("提示", "请输入DeepSeek API Key")
            return

        self.converting = True
        self.convert_btn.config(state=tk.DISABLED)
        self.preview_btn.config(state=tk.DISABLED)
        self.save_btn.config(state=tk.DISABLED)
        self.progress_var.set(0)

        for lbl in self.stage_labels:
            lbl.config(foreground="gray", font=("Helvetica", 9))

        thread = threading.Thread(target=self._convert_worker, args=(api_key,), daemon=True)
        thread.start()

    def _convert_worker(self, api_key):
        log.info("=" * 50)
        log.info("开始转换流程")
        try:
            client = DeepSeekClient(api_key)
            genre = self.genre_var.get()
            density = self.density_var.get()
            title = self.title_var.get()
            log.info(f"配置: genre={genre}, density={density}, title={title}")
            log.info(f"文本长度: {len(self.story_text)}字")

            # ---- 阶段1:模板生成(本地,无需缓存)----
            log.info(">>> 阶段1:模板生成")
            self.root.after(0, lambda: self._set_stage(0, True))
            self._update_status("阶段1:生成转换模板...")
            template = generate_template(genre)
            self.root.after(0, lambda: self.progress_var.set(10))
            self._update_status(f"阶段1完成:{genre}模板已生成")
            self.root.after(0, lambda: self._set_stage(0, False))
            log.info(f"阶段1完成: genre={template.get('genre')}")

            # ---- 阶段2:粗筛提取(检查缓存)----
            log.info(">>> 阶段2:粗筛提取")
            self.root.after(0, lambda: self._set_stage(1, True))
            cached_entities = get_cached("stage2", self.story_text, genre, density, title)
            if cached_entities:
                entities = cached_entities
                self._update_status("阶段2:使用缓存结果")
                log.info("阶段2使用缓存")
            else:
                self._update_status("阶段2:提取游戏要素...")
                entities = extract_entities(self.story_text)
                set_cached("stage2", self.story_text, genre, density, title, entities)
                log.info("阶段2结果已缓存")

            self.root.after(0, lambda: self.progress_var.set(25))
            self._update_status(f"阶段2完成:人物{len(entities['characters'])}个, "
                              f"地点{len(entities['locations'])}个, "
                              f"物品{len(entities['items'])}个")
            self.root.after(0, lambda: self._set_stage(1, False))

            # ---- 阶段3:AI精滤(检查缓存)----
            log.info(">>> 阶段3:AI精滤")
            self.root.after(0, lambda: self._set_stage(2, True))
            cached_structure = get_cached("stage3", self.story_text, genre, density, title)
            if cached_structure:
                game_structure = cached_structure
                self._update_status("阶段3:使用缓存结果")
                log.info("阶段3使用缓存")
            else:
                self._update_status("阶段3:AI精滤设计游戏结构...")
                game_structure = refine_with_ai(client, template, entities, self.story_text, title)
                if not game_structure.get("rooms"):
                    log.error("阶段3结果无rooms字段")
                    raise RuntimeError("AI未能生成有效的游戏结构")
                set_cached("stage3", self.story_text, genre, density, title, game_structure)
                log.info("阶段3结果已缓存")

            self.root.after(0, lambda: self.progress_var.set(50))
            room_count = len(game_structure.get("rooms", []))
            self._update_status(f"阶段3完成:{room_count}个房间, "
                              f"{len(game_structure.get('npcs', []))}个NPC")
            self.root.after(0, lambda: self._set_stage(2, False))

            # ---- 阶段4:生成HTML场景(检查缓存)----
            log.info(">>> 阶段4:生成HTML场景")
            self.root.after(0, lambda: self._set_stage(3, True))
            cached_scenes = get_cached("stage4", self.story_text, genre, density, title)
            if cached_scenes:
                mud_data = cached_scenes
                self._update_status("阶段4:使用缓存结果")
                log.info("阶段4使用缓存")
            else:
                self._update_status("阶段4:生成互动场景和选择分支...")
                mud_data = generate_scenes_from_structure(client, game_structure, self.story_text)
                if not mud_data.get("scenes"):
                    log.warning("阶段4返回无scenes,使用降级方案")
                    self._update_status("降级:使用游戏结构直接构建场景...")
                    mud_data = {
                        "title": title,
                        "scenes": _fallback_scenes(game_structure)
                    }
                if not mud_data.get("title"):
                    mud_data["title"] = title
                set_cached("stage4", self.story_text, genre, density, title, mud_data)
                log.info("阶段4结果已缓存")

            self.root.after(0, lambda: self.progress_var.set(85))
            self._update_status("正在生成HTML文件...")

            template_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
                                         "templates", "mud_template.html")
            self.html_output = build_html(mud_data, template_path)

            # 自动保存到output目录
            output_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "output")
            os.makedirs(output_dir, exist_ok=True)
            safe_title = "".join(c for c in title if c not in r'\/:*?"<>|').strip() or "mud_game"
            output_path = os.path.join(output_dir, f"{safe_title}.html")
            with open(output_path, "w", encoding="utf-8") as f:
                f.write(self.html_output)
            self.last_output_path = output_path
            log.info(f"HTML已保存: {output_path}")

            self.root.after(0, lambda: self.progress_var.set(100))
            scene_count = len(mud_data.get("scenes", []))
            self._update_status(f"完成! 已保存到 output/{safe_title}.html")
            self.root.after(0, lambda: self._set_stage(3, False))

            self.root.after(0, lambda: self.preview_btn.config(state=tk.NORMAL))
            self.root.after(0, lambda: self.save_btn.config(state=tk.NORMAL))

        except Exception as e:
            import traceback
            err_msg = str(e)
            log.error(f"转换失败: {err_msg}")
            log.error(traceback.format_exc())
            self._update_status(f"错误: {err_msg}")
            self.root.after(0, lambda msg=err_msg: messagebox.showerror("转换失败", msg))

        finally:
            self.converting = False
            self.root.after(0, lambda: self.convert_btn.config(state=tk.NORMAL))
            for i in range(4):
                self.root.after(0, lambda idx=i: self._set_stage(idx, False))

    def _update_status(self, text):
        self.root.after(0, lambda: self.status_label.config(text=text))

    def _preview_html(self):
        if not self.html_output:
            return

        import webbrowser

        if self.last_output_path and os.path.exists(self.last_output_path):
            webbrowser.open(f"file://{self.last_output_path}")
        else:
            import tempfile
            tmp = tempfile.NamedTemporaryFile(suffix=".html", delete=False, mode="w", encoding="utf-8")
            tmp.write(self.html_output)
            tmp.close()
            webbrowser.open(f"file://{tmp.name}")

    def _clear_cache(self):
        count = get_cache_size()
        if count == 0:
            messagebox.showinfo("提示", "缓存为空")
            return
        if messagebox.askyesno("确认", f"确定清空 {count} 个缓存文件?"):
            cleared = clear_cache()
            messagebox.showinfo("已清空", f"已清除 {cleared} 个缓存文件")

    def _save_html(self):
        if not self.html_output:
            return

        title = self.title_var.get() or "mud_game"
        default_name = f"{title}.html"

        path = filedialog.asksaveasfilename(
            defaultextension=".html",
            filetypes=[("HTML文件", "*.html")],
            initialfile=default_name
        )
        if not path:
            return

        try:
            with open(path, "w", encoding="utf-8") as f:
                f.write(self.html_output)
            messagebox.showinfo("保存成功", f"HTML游戏已保存到:\n{path}")
        except Exception as e:
            messagebox.showerror("保存失败", str(e))

    def _refresh_genre_list(self):
        self.genre_combo["values"] = get_genre_list()

    def _on_genre_change(self, event=None):
        pass

    def _save_template(self):
        genre = self.genre_var.get()
        # 只有内置模板可以作为基础保存为自定义
        template = generate_template(genre)

        name = tk.simpledialog.askstring("保存模板", "输入模板名称:", initialvalue=f"{genre}_自定义")
        if not name:
            return

        try:
            path = save_template(name, template)
            self._refresh_genre_list()
            self.genre_var.set(name)
            messagebox.showinfo("保存成功", f"模板已保存:\n{path}")
        except Exception as e:
            messagebox.showerror("保存失败", str(e))

    def _delete_template(self):
        genre = self.genre_var.get()
        if genre in ["仙侠", "玄幻", "武侠", "悬疑", "科幻", "通用"]:
            messagebox.showinfo("提示", "内置模板不可删除")
            return

        if not messagebox.askyesno("确认", f"确定删除模板 '{genre}' ?"):
            return

        if delete_template(genre):
            self._refresh_genre_list()
            self.genre_var.set("通用")
            messagebox.showinfo("已删除", f"模板 '{genre}' 已删除")
        else:
            messagebox.showerror("错误", "删除失败")

    def _load_config(self):
        if not os.path.exists(CONFIG_PATH):
            return
        try:
            with open(CONFIG_PATH, "r", encoding="utf-8") as f:
                config = json.load(f)
            if config.get("api_key"):
                self.api_key_var.set(config["api_key"])
        except Exception:
            pass

    def _save_config(self):
        config = {}
        if os.path.exists(CONFIG_PATH):
            try:
                with open(CONFIG_PATH, "r", encoding="utf-8") as f:
                    config = json.load(f)
            except Exception:
                pass

        config["api_key"] = self.api_key_var.get().strip()

        try:
            with open(CONFIG_PATH, "w", encoding="utf-8") as f:
                json.dump(config, f, ensure_ascii=False, indent=2)
            messagebox.showinfo("保存成功", "API Key 已保存")
        except Exception as e:
            messagebox.showerror("保存失败", str(e))


def _fallback_scenes(game_structure: Dict) -> List[Dict]:
    """降级方案:从game_structure直接构建简单场景"""
    scenes = []
    rooms = game_structure.get("rooms", [])
    for i, room in enumerate(rooms):
        scene_id = "scene_start" if i == 0 else f"scene_{room.get('id', i)}"
        choices = []
        exits = room.get("exits", {})
        for direction, target_room in exits.items():
            target_id = f"scene_{target_room}" if target_room != rooms[0].get("id") else "scene_start"
            choices.append({
                "text": f"向{direction}走去",
                "next_scene": target_id,
                "effect": ""
            })
        if not choices and i < len(rooms) - 1:
            choices.append({
                "text": "继续前行",
                "next_scene": f"scene_{rooms[i+1].get('id', i+1)}",
                "effect": ""
            })

        scenes.append({
            "id": scene_id,
            "title": room.get("name", f"场景{i+1}"),
            "description": room.get("description", "你来到了一个新的地方。"),
            "choices": choices
        })
    return scenes


2、截图:

游戏示例.png (117.89 KB, 下载次数: 2)

游戏示例.png

运行界面.png (102.91 KB, 下载次数: 0)

运行界面.png

豆兵记.zip

13.46 KB, 下载次数: 42, 下载积分: 吾爱币 -1 CB

游戏示例

免费评分

参与人数 3吾爱币 +3 热心值 +3 收起 理由
bzhongshan + 1 + 1 我很赞同!
苇间风 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
131fan + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
s77710604 发表于 2026-6-26 17:24
现在都可以这样玩了?表示大佬厉害,必须膜拜,我要试试,之前就有好多小说为什么不能转成游戏的想法,得偿所愿
沙发
0易水寒0 发表于 2026-6-26 14:49
3#
Jingnan0405 发表于 2026-6-26 14:54
我去我去,这个想法很有趣,体验一下试试。
4#
tonybord 发表于 2026-6-26 15:07
好神奇的角度
5#
leeclam 发表于 2026-6-26 15:14
作都玩他自己写的小说游戏会不会玩得不明不白?
6#
838384855 发表于 2026-6-26 15:20
Jingnan0405 发表于 2026-6-26 14:54
我去我去,这个想法很有趣,体验一下试试。

怎么样 老哥
7#
jxcyzw 发表于 2026-6-26 15:39
这个游戏挺有意思的,小说还能有这样的玩法,感谢分享!
8#
ysjd22 发表于 2026-6-26 16:34
MUD游戏……20多年前的游戏模式,泡论坛专用
9#
danfeng999 发表于 2026-6-26 16:51
太有趣了,我来尝尝咸淡
10#
AC001 发表于 2026-6-26 16:51
打开新思路,确实不错
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-6-27 05:56

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表