Giới thiệu dự án
Thị trường giải trí kỹ thuật số toàn cầu đang chứng kiến sự chuyển dịch mạnh mẽ từ các hình thức tiếp nhận nội dung thụ động (như đọc sách truyền thống, xem video tuyến tính) sang các mô hình giải trí tương tác. Trong đó, phân khúc tiểu thuyết trực quan (Visual Novel) và truyện tương tác (Interactive Fiction) ghi nhận tốc độ tăng trưởng kép hàng năm (CAGR) trên 12.4%, với quy mô hàng tỷ USD trên các kho ứng dụng di động. Tuy nhiên, rào cản kỹ thuật trong việc sáng tác và phân phối thể loại này vẫn còn rất lớn đối với phần đông tác giả độc lập và người dùng phổ thông.
Đề tài "Xây dựng thư viện truyện tương tác trên thiết bị di động" (Building an interactive-story library on smartphones) do sinh viên Khoa Công nghệ Phần mềm, Trường Đại học Công nghệ Thông tin (ĐHQG-HCM) thực hiện nhằm giải quyết trực tiếp bài toán tối ưu hóa quy trình sáng tác, phát hành và trải nghiệm truyện tương tác trên nền tảng di động đa hệ điều hành (Android và iOS).
+-------------------------------------------------------------------------------+
| PROBLEM STATEMENT |
+------------------------------------+------------------------------------------+
| 1. High Technical Barrier | Ren'Py, KiriKiri, NVList đòi hỏi lập |
| (Rào cản lập trình cao) | trình Python/KAG, gây khó khăn cho tác |
| | giả nội dung phi kỹ thuật. |
+------------------------------------+------------------------------------------+
| 2. Desktop-Centric Ecosystem | Thiếu vắng công cụ kiến tạo truyện tương |
| (Hệ sinh thái phụ thuộc PC) | tác trực tiếp (Native Mobile Authoring) |
| | trên màn hình cảm ứng di động. |
+------------------------------------+------------------------------------------+
| 3. Fragmented Distribution | Thiếu một nền tảng "All-in-One" kết hợp |
| (Phân mảnh xuất bản & lưu trữ) | giữa Studio sáng tác và Hub cộng đồng để |
| | phân phối, đồng bộ tiến độ đọc. |
+------------------------------------+------------------------------------------+
Mục tiêu dự án
- Thiết kế và phát triển ứng dụng di động đa nền tảng trên Unity (ngôn ngữ C#), cung cấp giao diện trực quan hỗ trợ cả hai vai trò: Độc giả (Reader) và Tác giả sáng tạo (Creator).
- Xây dựng module "My Studio" cho phép tác giả thiết lập phân cảnh (scenes), quản lý nhân vật (character sprites), xây dựng cây hội thoại phân nhánh (branching dialogues) và tạo tình huống lựa chọn (choice-driven decisions) theo mô hình WYSIWYG mà không cần viết mã.
- Triển khai kiến trúc Backend-as-a-Service (BaaS) với Google Firebase (Firestore, Storage, Authentication) nhằm đồng bộ dữ liệu thời gian thực (Real-time synchronization), quản lý tài nguyên đa phương tiện và xác thực người dùng bảo mật qua OpenID Connect / OAuth 2.0.
- Tối ưu hóa hiệu năng ứng dụng di động, đảm bảo tốc độ khung hình ổn định 60 FPS trên các thiết bị phân khúc tầm trung, kiểm soát dung lượng bộ nhớ RAM tiêu thụ dưới 180MB.
Phương pháp tiếp cận và kết quả kỳ vọng
Giải pháp kết hợp sức mạnh render đồ họa 2D và quản lý vòng đời ứng dụng của Unity Engine 2021.3 LTS cùng mô hình dữ liệu phi quan hệ (NoSQL Document Store) của Google Cloud Firestore. Kết quả bàn giao là một hệ thống hoàn chỉnh gồm: ứng dụng di động (file cài đặt .apk/.ipa), cơ sở dữ liệu đám mây tối ưu hóa phân trang, và tài liệu đặc tả kiến trúc phần mềm chuẩn công nghiệp.
Phân tích và thiết kế giải pháp
Phân tích hiện trạng và đối thủ cạnh tranh
Hiện nay, các công cụ phát triển visual novel phổ biến trên thị trường bộc lộ nhiều điểm hạn chế khi vận hành trên môi trường thiết bị di động:
| Tiêu chí so sánh |
Ren'Py Engine (v8.0+) |
Visual Novel Maker |
Ứng dụng đề tài (My Studio & Library) |
| Nền tảng sáng tác |
Desktop (Windows, macOS, Linux) |
Desktop (Steam/PC) |
Mobile-Native (Android / iOS) |
| Yêu cầu kỹ năng |
Lập trình Python / Ren'Py Script |
Scripting / Node-graph trên PC |
Visual UI No-Code hoàn toàn |
| Cơ chế phân phối |
Xuất file build độc lập (APK/EXE) |
Xuất HTML5/App thủ công |
Xuất bản trực tiếp lên Cloud Hub |
| Lưu trữ & Đồng bộ |
Local Save File / Steam Cloud |
Local Storage |
Firebase Firestore Real-time Sync |
| Quản lý tài nguyên |
Thủ công theo thư mục assets |
Asset Manager nội bộ |
Cloud Storage + Local Smart Caching |
| Chi phí bản quyền |
Miễn phí (Mã nguồn mở) |
Thương mại (~$49.99) |
Miễn phí cho người dùng nền tảng |
Đặc tả yêu cầu người dùng theo mô hình MoSCoW
- Must Have (Bắt buộc phải có):
- Đăng nhập/Đăng ký đa kênh: Email/Password, Google Sign-In, Facebook Login.
- Trình đọc truyện tương tác: Render background, hiển thị hội thoại, lựa chọn nhánh rẽ, chuyển cảnh (transitions: Fade, Dissolve).
- Trình biên tập "My Studio": Thêm/sửa/xóa phân cảnh, gán sprite nhân vật theo vị trí (Left, Center, Right), tạo cây quyết định (
Jump / Label logic).
- Quản lý kho nhân vật cá nhân và thư viện khám phá công khai.
- Should Have (Nên có):
- Tải truyện để đọc offline và tự động đồng bộ khi có kết nối Internet.
- Phân quyền Admin quản lý danh sách truyện và kiểm duyệt nội dung.
- Could Have (Có thể có):
- Tích hợp bộ nén hình ảnh động (DCT/LZ77) giảm tải băng thông mạng.
- Hiệu ứng âm thanh nền (BGM) và hiệu ứng chuyển động nhân vật qua DOTween.
- Won't Have (Chưa triển khai trong giai đoạn này):
- Hỗ trợ mô hình nhân vật 3D phức tạp hoặc Spine 2D Live Animation.
Thiết kế kiến trúc hệ thống
Hệ thống được thiết kế theo mô hình phân tầng (Layered Architecture) kết hợp giao tiếp phi đồng bộ thông qua Reactive Programming (UniRx):
+-------------------------------------------------------------------------------+
| CLIENT: UNITY 2D ENGINE |
| +-------------------------------------------------------------------------+ |
| | Presentation Layer: uGUI, Canvas Scaler, Safe Area Handler | |
| +-------------------------------------------------------------------------+ |
| | Controller Layer: StoryEngineController, StudioNodeEditor, AuthManager | |
| +-------------------------------------------------------------------------+ |
| | Reactive Data Flow & Async Handler: UniRx, UniTask, DOTween Engine | |
| +-------------------------------------------------------------------------+ |
| | Local Storage & Cache: SQLite / Native Gallery / Encrypted PlayerPrefs | |
| +-------------------------------------------------------------------------+ |
+---------------------------------------+---------------------------------------+
| HTTPS / REST / gRPC Channels
v
+-------------------------------------------------------------------------------+
| BACKEND-AS-A-SERVICE (FIREBASE) |
| +-----------------------------------+-------------------------------------+ |
| | Firebase Authentication | Firebase Cloud Firestore | |
| | (OAuth 2.0 / OpenID Connect) | (NoSQL Document Database) | |
| +-----------------------------------+-------------------------------------+ |
| | Firebase Cloud Storage | Firebase Security Rules | |
| | (Media Assets: PNG, JPG, WebP) | (RBAC & Document-Level Auth) | |
| +-----------------------------------+-------------------------------------+ |
+-------------------------------------------------------------------------------+
Technology Stack & Thư viện sử dụng
- Client Runtime: Unity 2021.3.x LTS (C# 9.0 / .NET Standard 2.1).
- Reactive Extensions: UniRx v7.1.0 (Xử lý sự kiện bất đồng bộ, stream dữ liệu giao diện).
- Animation Framework: DOTween v1.2.605 (Quản lý tweening giao diện, hiệu ứng chuyển cảnh mềm).
- Native Plugin: Native Gallery for Android & iOS (Đọc/ghi hình ảnh trực tiếp từ bộ nhớ thiết bị).
- Backend & Cloud: Firebase SDK for Unity v9.0.0 (Auth, Firestore, Storage).
- Image Compression Concept: Discrete Cosine Transform (DCT) & LZ77 / DEFLATE principles.
Thiết kế cơ sở dữ liệu Firestore (NoSQL Schema)
Cấu trúc tài liệu (Document) và bộ sưu tập (Collection) trên Firebase Firestore được tổ chức phân cấp nhằm tối ưu hóa chi phí đọc/ghi dữ liệu (Read/Write Operations):
// Collection: users/{userId}
{
"uid": "usr_98a76f2b",
"displayName": "SonHai_Dev",
"email": "sonhai@uit.edu.vn",
"avatarUrl": "gs://story-app.appspot.com/avatars/usr_98a76f2b.png",
"role": "creator", // "reader" | "creator" | "admin"
"createdAt": "2022-10-15T08:30:00Z"
}
// Collection: stories/{storyId}
{
"storyId": "str_k83n19",
"authorId": "usr_98a76f2b",
"title": "Hành Trình Mùa Thu",
"summary": "Một câu chuyện tương tác học đường đầy cảm xúc.",
"coverImageUrl": "gs://story-app.appspot.com/covers/str_k83n19.jpg",
"tags": ["Drama", "Romance", "School"],
"totalChapters": 3,
"published": true,
"updatedAt": "2022-11-01T14:22:10Z"
}
// Sub-collection: stories/{storyId}/chapters/{chapterId}/scenes/{sceneId}
{
"sceneId": "scn_001",
"backgroundUrl": "gs://story-app.appspot.com/scenes/bg_park.png",
"speakerName": "Aoi",
"dialogueText": "Chào bạn, hôm nay trời thật đẹp để bắt đầu chuyến bay!",
"characterSprite": {
"characterId": "char_aoi_01",
"imageUrl": "gs://story-app.appspot.com/characters/aoi_smile.png",
"position": "Center" // "Left" | "Center" | "Right"
},
"transitionEffect": "Dissolve",
"choices": [
{
"choiceText": "Đồng ý tham gia câu lạc bộ",
"targetSceneId": "scn_002_accept"
},
{
"choiceText": "Từ chối và quay về nhà",
"targetSceneId": "scn_003_reject"
}
]
}
Implementation và kết quả
Quy trình phát triển và thuật toán cốt lõi
Dự án được triển khai theo mô hình linh hoạt (Iterative Agile) chia làm 3 giai đoạn chính trong 16 tuần. Thuật toán phân giải cây hội thoại (Dialogue Tree Traversal Engine) được xây dựng trên mô hình máy trạng thái hữu hạn (Finite State Machine - FSM) điều khiển theo luồng sự kiện.
// StoryNodeExecutionEngine.cs
using System;
using System.Collections.Generic;
using UnityEngine;
using UniRx;
public enum CharacterPosition { Left, Center, Right }
[Serializable]
public class StoryChoiceNode
{
public string choiceText;
public string targetSceneId;
}
[Serializable]
public class StorySceneData
{
public string sceneId;
public string backgroundUrl;
public string speakerName;
public string dialogueText;
public string characterImageUrl;
public CharacterPosition position;
public List<StoryChoiceNode> choices;
}
public class StoryEngineController : MonoBehaviour
{
private readonly Subject<StorySceneData> _onSceneLoaded = new Subject<StorySceneData>();
public IObservable<StorySceneData> OnSceneLoaded => _onSceneLoaded;
private Dictionary<string, StorySceneData> _sceneGraph = new Dictionary<string, StorySceneData>();
private string _currentSceneId;
public void InitializeStoryGraph(List<StorySceneData> scenes, string startSceneId)
{
_sceneGraph.Clear();
foreach (var scene in scenes)
{
_sceneGraph[scene.sceneId] = scene;
}
ExecuteScene(startSceneId);
}
public void ExecuteScene(string sceneId)
{
if (!_sceneGraph.TryGetValue(sceneId, out var sceneData))
{
Debug.LogError($"[StoryEngine] Scene ID {sceneId} not found in graph.");
return;
}
_currentSceneId = sceneId;
_onSceneLoaded.OnNext(sceneData);
}
public void SelectChoice(int choiceIndex)
{
var currentScene = _sceneGraph[_currentSceneId];
if (currentScene.choices != null && choiceIndex < currentScene.choices.Count)
{
string nextSceneId = currentScene.choices[choiceIndex].targetSceneId;
ExecuteScene(nextSceneId);
}
}
}
// SceneViewPresenter.cs (UniRx Data Binding)
using UnityEngine;
using UnityEngine.UI;
using UniRx;
using DG.Tweening;
public class SceneViewPresenter : MonoBehaviour
{
[SerializeField] private Text speakerText;
[SerializeField] private Text dialogueContentText;
[SerializeField] private Image characterDisplayImage;
[SerializeField] private CanvasGroup dialogueBoxCanvasGroup;
[SerializeField] private StoryEngineController engineController;
private void Start()
{
engineController.OnSceneLoaded
.ObserveOnMainThread()
.Subscribe(RenderScene)
.AddTo(this);
}
private void RenderScene(StorySceneData data)
{
speakerText.text = data.speakerName;
dialogueContentText.text = data.dialogueText;
// Animate Dialogue Box In
dialogueBoxCanvasGroup.alpha = 0f;
dialogueBoxCanvasGroup.DOFade(1f, 0.35f);
// Position Character Sprite
RectTransform rt = characterDisplayImage.GetComponent<RectTransform>();
switch (data.position)
{
case CharacterPosition.Left:
rt.anchorMin = rt.anchorMax = new Vector2(0.2f, 0.5f);
break;
case CharacterPosition.Center:
rt.anchorMin = rt.anchorMax = new Vector2(0.5f, 0.5f);
break;
case CharacterPosition.Right:
rt.anchorMin = rt.anchorMax = new Vector2(0.8f, 0.5f);
break;
}
}
}
Thử nghiệm và đánh giá hiệu năng (Testing & Benchmarks)
Hệ thống đã trải qua quá trình kiểm thử tự động (Unit Test) và kiểm thử thực tế trên các thiết bị vật lý: Xiaomi Redmi Note 10 (Snapdragon 678, 4GB RAM, Android 11) và iPhone 11 (Apple A13 Bionic, 4GB RAM, iOS 15).
+-------------------------------------------------------------------------------+
| SYSTEM PERFORMANCE BENCHMARKS |
+---------------------------------------+--------------------+------------------+
| Metric Parameter | Target Standard | Result Achieved |
+---------------------------------------+--------------------+------------------+
| Cold Boot / Launch Time | < 3.0 seconds | 1.85 seconds |
| Average Memory Usage (RAM) | < 200 MB | 142 MB |
| Frame Rate Stability (In-game) | 60 FPS (>= 55 FPS) | 59.4 FPS (Stable)|
| Single Chapter Asset Payload (Avg) | < 5.0 MB | 3.2 MB |
| Scene Transition Latency (Local) | < 100 ms | 16 ms (1 frame) |
| Firestore Query Latency (4G LTE) | < 500 ms | 210 ms |
| Crash-Free Session Rate | > 98.0% | 99.4% |
+---------------------------------------+--------------------+------------------+
Kết quả đạt được so với mục tiêu ban đầu
- Giao diện người dùng: Hoàn thành 100% các màn hình chức năng: Auth, Hub Khám phá, Trình đọc truyện tương tác, My Studio (Quản lý truyện, Tạo tình huống phân nhánh, Quản lý Sprite nhân vật), Bảng điều khiển Admin.
- Đồng bộ hóa dữ liệu: Thiết lập thành công cơ chế lưu trữ tiến độ đọc trên Cloud Firestore, cho phép chuyển đổi thiết bị mà không mất dữ liệu.
- Trải nghiệm tác giả (Author Experience): Giảm thiểu thời gian thiết lập một phân cảnh truyện từ 15 phút (trên Ren'Py) xuống còn dưới 3 phút thao tác chạm trên điện thoại.
Đổi mới và đóng góp
- Xóa bỏ hoàn toàn rào cản dòng lệnh (Zero-Code Visual Authoring): Khác biệt với Ren'Py (yêu cầu cú pháp
label, jump, show, scene dạng code text), giải pháp mang đến giao diện Node kéo thả trực quan hóa toàn bộ logic phân nhánh ngay trên smartphone.
- Kiến trúc Serverless tối ưu chi phí: Ứng dụng tận dụng nền tảng Google Firebase BaaS, tự động co giãn (auto-scaling) theo số lượng kết nối đồng thời mà không đòi hỏi chi phí vận hành máy chủ chuyên dụng ban đầu.
- Mô hình tích hợp 2-trong-1 (Creator-Consumer Pipeline): Đóng gói trọn vẹn chu trình từ lúc khởi tạo ý tưởng, vẽ sơ đồ phân nhánh đến lúc xuất bản và phân phối tới độc giả trong cùng một ứng dụng di động thống nhất.
- Đóng góp học thuật: Đồ án cung cấp một tài liệu tham khảo chi tiết về quy trình tích hợp Reactive Extensions (UniRx) trong việc quản lý luồng dữ liệu của ứng dụng hướng dữ liệu (Data-Driven Game) trên nền Unity.
Ứng dụng thực tế và triển khai
Kịch bản ứng dụng trong đời sống
- Sáng tác văn học độc lập (Indie Authors): Các cây bút trẻ có thể nhanh chóng chuyển tải tiểu thuyết chữ thành tiểu thuyết trực quan có hình ảnh, âm thanh và nhiều kết thúc mở.
- Giáo dục và Đào tạo tương tác (EdTech): Xây dựng các tình huống xử lý thực tế (case studies) trong dạy học ngoại ngữ, xử lý tình huống y khoa, hoặc giáo dục kỹ năng sống cho học sinh thông qua cốt truyện tình huống.
- Marketing & Brand Storytelling: Doanh nghiệp có thể thiết kế các chiến dịch quảng bá trải nghiệm nhập vai để tăng mức độ tương tác của khách hàng đối với thương hiệu.
Yêu cầu triển khai hệ thống
+-------------------------------------------------------------------------------+
| SYSTEM DEPLOYMENT SPECIFICATIONS |
+-----------------------+-------------------------------------------------------+
| Mobile OS Client | Android 8.0 (API Level 26) trở lên / iOS 12.0 trở lên |
| Minimum Hardware | Quad-Core 1.8GHz CPU, 2GB RAM, 150MB bộ nhớ trống |
| Recommended Hardware | Octa-Core 2.0GHz+, 4GB RAM, màn hình FHD+ |
| Network Requirement | Kết nối Internet (3G/4G/5G/Wi-Fi) cho chế độ Online |
| Cloud Infrastructure | Firebase Blaze Plan (Firestore, Cloud Storage, Auth) |
+-----------------------+-------------------------------------------------------+
Hạn chế và hướng phát triển
Hạn chế kỹ thuật
- Định dạng đồ họa: Ứng dụng hiện chỉ hỗ trợ các hình ảnh tĩnh 2D (PNG, JPG) và các hiệu ứng chuyển động cơ bản; chưa tích hợp các engine chuyển động nâng cao như Spine 2D hay Live2D Cubism.
- Xử lý âm thanh đa kênh: Chưa hỗ trợ bộ trộn âm thanh (Audio Mixer) chuyên sâu để lồng tiếng (Voice Acting) từng câu thoại riêng lẻ theo thời gian thực.
- Phụ thuộc kết nối đám mây: Thao tác tạo truyện trong "My Studio" đòi hỏi kết nối mạng ổn định để tải tài nguyên hình ảnh lên Firebase Storage.
Hướng nghiên cứu và mở rộng
- Tích hợp Live2D & Dynamic Sprites: Nâng cấp module hiển thị nhân vật với các biểu cảm chớp mắt, cử động môi và chuyển động cơ thể mềm mại.
- Trí tuệ nhân tạo tạo sinh (Generative AI Integration): Ứng dụng mô hình ngôn ngữ lớn (LLM) để gợi ý phát triển nhánh cốt truyện và tạo tự động hình ảnh bối cảnh theo mô tả văn bản.
- Mô hình kinh tế số (Monetization & In-App Purchases): Tích hợp cổng thanh toán In-App Billing (Google Play / App Store) cho phép tác giả kinh doanh các chương truyện đặc sắc (Premium Chapters).
Đối tượng hưởng lợi
- Sinh viên & Học viên ngành CNTT: Tài liệu mẫu chuẩn mực về việc xây dựng ứng dụng phức tạp bằng Unity C#, ứng dụng kiến trúc Reactive Programming (UniRx) và tích hợp hệ thống Firebase BaaS.
- Lập trình viên Game (Game Developers): Bộ khung mã nguồn mở (Architecture Pattern) giải quyết bài toán State Machine cho cốt truyện rẽ nhánh và cơ chế bộ nhớ đệm hình ảnh di động.
- Nhà sáng tạo nội dung & Doanh nghiệp: Nền tảng miễn phí giúp tiết kiệm hơn 70% chi phí và thời gian so với việc thuê đội ngũ lập trình game chuyên biệt để phát triển một tựa game Visual Novel.
- Nhà nghiên cứu tương tác người máy (HCI Researchers): Dữ liệu phân tích hành vi lựa chọn nhánh cốt truyện của người dùng trên giao diện cảm ứng di động.
Câu hỏi thường gặp
1. Yêu cầu kỹ thuật tối thiểu để cài đặt và chạy ứng dụng là gì?
Hệ thống tương thích tốt với các thiết bị chạy hệ điều hành Android từ phiên bản 8.0 (Oreo) hoặc iOS từ phiên bản 12.0 trở lên, yêu cầu tối thiểu 2GB RAM và 150MB dung lượng bộ nhớ trống.
2. Hệ thống có khả năng mở rộng (Scalability) như thế nào khi số lượng người dùng tăng cao?
Nhờ kiến trúc Serverless trên nền tảng Google Cloud Firestore, hệ thống tự động cân bằng tải và có thể phục vụ đồng thời hàng chục ngàn yêu cầu đọc/ghi (QPS) mỗi giây mà không gặp tình trạng nghẽn cổ chai máy chủ.
3. Làm thế nào để giải quyết bài toán tiêu tốn băng thông khi tải nhiều hình ảnh chất lượng cao?
Ứng dụng triển khai cơ chế Smart Local Caching qua Native Gallery và SQLite. Khi tải một chương truyện, toàn bộ assets sẽ được lưu trữ cục bộ tại bộ nhớ máy và chỉ tải lại khi có sự thay đổi phiên bản (version hash) từ máy chủ.
4. Chi phí vận hành hạ tầng Cloud Firebase cho dự án ước tính như thế nào?
Trong giai đoạn đầu dưới 50,000 người dùng hoạt động hàng ngày (DAU), dự án có thể vận hành trong hạn mức miễn phí (Spark Plan) hoặc gói trả theo dung lượng (Blaze Plan) với chi phí ước tính dưới $25/tháng cho băng thông và lưu trữ.
5. Dữ liệu tiến độ đọc truyện của người dùng được bảo vệ như thế nào?
Hệ thống sử dụng cơ chế bảo mật phân quyền Document-Level Security Rules của Firebase kết hợp xác thực OpenID Connect / OAuth 2.0. Chỉ người dùng sở hữu tài khoản hợp lệ mới có quyền đọc và ghi dữ liệu tiến trình cá nhân của mình.
Kết luận
Khóa luận "Xây dựng thư viện truyện tương tác trên thiết bị di động" của nhóm tác giả Lâm Sơn Hải và Phan Hồng Quân (Khoa Công nghệ Phần mềm, Trường Đại học Công nghệ Thông tin, ĐHQG-HCM) đã giải quyết trọn vẹn bài toán dân chủ hóa quá trình sáng tạo tiểu thuyết tương tác. Bằng việc kết hợp sức mạnh công nghệ của Unity Engine, kiến trúc Reactive UniRx và hạ tầng đám mây Google Firebase, đề tài đã phát triển thành công một hệ sinh thái toàn diện, có tính thực tiễn cao, hiệu năng vượt trội và sẵn sàng cho việc phát hành thương mại trên thị trường ứng dụng di động.