להפוך את „תוחלת החיים של גוף-תוכנה” (《软件体的生命周期》) ל־Visual Novel שאפשר לשחק בו: רטרוספקטיבה מלאה של איטרציה
הפעם זה לא „להלביש סקין של קורא”, אלא להפוך את הטקסט המלא 软件体的生命周期.md באמת לרומן חזותי בסגנון GALGAME יפני שאפשר לשחק בו, ובמקביל להיצמד מתחילה ועד סוף לאילוץ קשיח: אפשר רק להוסיף על הטקסט המקורי—אי אפשר לגרוע; אסור לאבד אף פרט טקסטואלי.
כל התהליך לא היה יציקה אחת וגמרנו, אלא איטרציה רציפה אופיינית של „קודם לגרום לזה לעבוד, ואז לשייף לאט לאט את תחושת הזרות”. במבט לאחור אפשר לחלק את זה בערך לשלבים הבאים.
1. נקודת ההתחלה הייתה ברורה: לא עיבוד מקוצר, אלא המרה נאמנה של כל הטקסט
מההתחלה היעד היה נוקשה:
- מקור התסריט הוא הקובץ המקומי
软件体的生命周期.md - כל הטקסט חייב להיכנס למשחק
- אי אפשר בגלל שזה משחק למחוק את המקור ולהפוך אותו לתמצית, לגרסת דיאלוגים או לגרסת „לייט נובל”
- אפשר לחזק את אופן ההצגה, אבל תוכן הטקסט עצמו לא יכול להתכווץ
לכן רעיון הבסיס בפרויקט הזה לא היה „לכתוב תסריט VN”, אלא „לחתוך את הטקסט המקורי למבנה פסקאות שמתאים להתקדמות של רומן חזותי, תוך שמירה על האפשרות לצפות מחדש במקור המלא”.
בהמשך, בכל המערכת—כמו ניווט פרקים, סקירת מקור, איתור לפי פסקה, צפייה חוזרת, ושמירת התקדמות—הכול בעצם משרת את ההנחה הזו.
2. הגרסה הראשונה רצה, אבל לא נראתה כמו Visual Novel
אחרי שהגרסה הראשונה יצאה, הבעיה הגדולה לא הייתה חסר בפיצ’רים אלא שהאופי לא היה נכון.
אמנם כבר היה אפשר להתקדם בטקסט, להציג תוכן ולחלק לפסקאות, אבל הממשק נראה יותר כמו קורא דפי־ווב עם לוח בקרה, ולא כמו GALGAME יפני. התגובה הראשונה של המשתמש הייתה ישירה: „הממשק הזה פשוט לא נכון; תעשה UI בסגנון galgame יפני.”
אז בסבב הריפקטורינג הראשון, הפוקוס לא היה להוסיף יכולות, אלא קודם ליישר את השפה הוויזואלית:
- להפריד מחדש בין שכבת במה, שכבת קדמה ושכבת תיבת טקסט
- לעצב מחדש כותרות פרק, עמוד שם הספר וכרטיסי מעבר בסגנון רומן חזותי
- להפוך את תיבת הטקסט לדיאלוג VN מקובע על הבמה, במקום כרטיס וובי רגיל
- לבנות אזור דיבור לדמות, לוחית שם, פס התקדמות וכפתור התקדמות בפריסה שדומה יותר לרומן חזותי יפני
המשמעות של הסבב הזה הייתה: קודם לגרום לזה להיראות כמו משחק, ואז להמשיך להשלים את האינטראקציות שמצפים ממשחק.
3. השלמת איורי הדמויות, והבמה התפתחה מ„יש תמונות” ל„זה מרגיש כמו במה”
למשתמש הייתה דרישה ברורה: לכל דמות חייב להיות איור דמות (立绘).
לכן ההמשך לא היה פשוט לשים תמונות לכמה דמויות ראשיות, אלא להקים באמת מערכת איורי דמויות:
- נתוני איורי הדמויות מנוהלים בנפרד
- לכל דמות יש מיקום על הבמה וסגנון תצוגה משלה
- פריסה אפשרית לדמות יחידה, מספר דמויות, וריבוי דמויות על אותה במה
- כשהדמות מדברת יש מצב מודגש, ודמויות מאזינות מוחלשות
- טקסט הדיאלוג תומך בצבע תואם לכל דמות
גם החלק הזה עבר הרבה ליטוש. באמצע הופיעו כמה בעיות טיפוסיות:
- יש דמויות שמוצגות רק מהמותניים ומטה
- תיבת הטקסט גדולה מדי וחוסמת את הבמה
- כשיש כמה דמויות יחד, הבמה מרגישה צפופה
- בתמונות הממוזערות של השמירה, האיור נחתך בראש או נשארות רק רגליים
אחר כך תיקנתי סביב זה בהרבה סבבים:
- התאמת גובה הבמה ולוגיקת הסקייל של איורי הדמויות
- הפרדה בין שלוש קטגוריות גודל: human / digital / entity
- לאפשר הזזה אופקית/אנכית וסקייל לבמה כולה
- חלוקת slot הגיונית יותר לריבוי דמויות
- תיקון קומפוזיציית התמונה הממוזערת כדי לשמור ככל האפשר על גוף מלא ולהימנע מחיתוך מכוער בכרטיסי השמירה
אחרי זה זה כבר לא היה „רק כמה תמונות שמונחות”, אלא התחיל להיות לזה „חוש במה” ברור.
4. החופש של תיבת הטקסט כמעט הפך למערכת פריסה מתכווננת
בפרויקט הזה תיבת הטקסט הייתה המקום שהמשתמש היה עליו הכי קפדן, וגם המקום שהגיע הכי עמוק.
המשתמש העלה רצף דרישות מאוד ספציפיות:
- תמיכה בהגדרת מיקום תיבת הטקסט על ידי המשתמש
- תמיכה בשינוי גודל מהפינות
- תמיכה בכיוונון שקיפות
- מהירות טקסט—הכי מהיר: להופיע מייד (instant)
- תמיכה בצבע טקסט שונה לכל דמות
- תיבת הטקסט לא יכולה להיות נעולה על רוחב מלא
- אפשר לצמצם ואפשר להרחיב
- לא לחסום תמיד את האיורים
- בפריסת שונְשִׁי (右侧布局) צריך להצמיד לימין הכי קיצוני
לכן זה לא הסתיים ב„אפשר לגרור את תיבת הטקסט”, אלא בהדרגה הפך למערכת פריסה מלאה:
- תמיכה בגרירה להזזת תיבת הטקסט
- תמיכה בסקייל בשמונה כיוונים: ארבע צלעות וארבע פינות
- התאמת רוחב וגובה בחופשיות
- פריסטים: מרכז, שמאל־למטה, ימין־למטה, שמאל־למעלה, ימין־למעלה
- שקיפות, גודל גופן ומרווח שורות
- שמירת התאמות יחד עם ההתקדמות ושחזור בפעם הבאה
- שינוי מיקום תיבת הטקסט מפעיל „הימנעות” של הבמה כדי להפחית חסימה של דמויות
כאן היה תפנית מאוד קריטית:
בהתחלה אמנם הייתה תמיכה בשינוי גודל, אבל עדיין הייתה בעיה של „הכי צר זה עדיין רוחב מלא” ו„ויזואלית זה מרגיש נעול”. אחר כך תיקנתי במיוחד את רוחב המינימום, רוחב ברירת המחדל ולוגיקת המידות המותאמות אישית—ורק אז זה באמת הגיע לחופש שינוי שהמשתמש רצה, ולא „נראה שאפשר לכוון, אבל בפועל אי אפשר”.
5. כותרות, מעברי פרקים ומידע מציין־מקום—שוב ושוב עשינו פחות
כיוון איטרציה ברור נוסף היה להוריד בהדרגה UI מיותר שמקטע את הקריאה.
המשתמש התלונן על כמה דברים אופייניים:
- שני הריבועים בפינה שמאלית־עליונה—אפשר שייעלמו אוטומטית ולא יישאר placeholder
- שם הספר וכותרת ענקית „פרק x” יופיעו רק פעם אחת בעת מעבר פרק, לא בכל משפט
- לא לתלות תמיד בלוקים של הסברים על המסך
אז עשיתי כמה סבבים של „להופיע רק כשצריך”:
- עמוד שם הספר / כותרת פרק—להופיע קצר רק במעבר פרק אמיתי
- במצב קריאה רגיל—הסתרה אוטומטית של כותרות ענק ו־placeholders
- בסצנות בלי איורי דמויות—לא להציג כרטיס placeholder גדול
- HUD עליון—דוהה אוטומטית אחרי חוסר פעילות
- רמזי קריאה—במחשב שולחני יוצאים אוטומטית אחרי חוסר פעילות
- רמזי גרירה וידיות סקייל נחלשים בזמן קריאה שקטה, וחוזרים רק בזמן אינטראקציה
- תגיות ליד רגלי הדמות דוהות אוטומטית בזמן קריאה שקטה, ונידלקות שוב בעת אינטראקציה או שינוי דמות
כל סדרת ההתאמות הזו בעצם עושה אותו דבר:
להנמיך את תחושת „ממשק כלי” ולהרים את תחושת „בימוי קריאה”.
6. השלמת דרכי ההתקדמות—חוויית שימוש יותר כמו רומן חזותי אמיתי
מעבר להתקדמות הבסיסית, השלמתי גם הרגלי אינטראקציה נפוצים של VN:
- לחיצה מחוץ לתיבת הטקסט—מתקדמת
- גלגלת עכבר: הבא / הקודם
- רווח, Enter, חיצים—התקדמות
- ניגון אוטומטי
- דילוג על טקסט שכבר נקרא
- קליק ימני או מקש קיצור להסתרת הממשק
- לחיצה ארוכה באזור ריק להסתרת הממשק (מובייל)
גם כאן זה לא היה נכון מהפעם הראשונה.
למשל, תיקון קטן שעשיתי לאחרונה: כשמראים את הבקרה הגלגלת עובדת, אבל כשמקפלים את הבקרה הגלגלת מפסיקה לעבוד. הסיבה הייתה שאזור הטקסט סווג בטעות כאזור ש„צריך ליירט גלילה”. אחרי שתיקנתי את התנאי הזה, הוספתי גם חזרה אוטומטית, כדי להבטיח שבהמשך „אחרי קיפול הבקרה, אם העכבר על טקסט התוכן—הגלגלת עדיין מקדמת קדימה/אחורה”.
תיקונים כאלה קטנים אבל קריטיים, כי הם קובעים ישירות אם המוצר מרגיש כמו VN שאפשר באמת לקרוא בו לאורך זמן.
7. שמירה, צפייה חוזרת, סקירת מקור—הפעם זה לא פיצ’ר צדדי, אלא פיצ’ר ליבה
כי הפרויקט הזה דרש „נאמנות למקור” מההתחלה, אז פיצ’רים שבמשחקים רגילים הם תוספת—כאן הם פונקציות עיקריות:
- שמירה אוטומטית
- שמירה מהירה / טעינה מהירה
- שמירה ידנית בריבוי סלוטים
- בעת טעינה—שחזור מיקום/גודל תיבת הטקסט והעדפות קריאה
- צפייה חוזרת בפסקאות האחרונות
- ניווט פרקים
- סקירת מקור מלאה ותוכן עניינים
- חיפוש־לאחור מהפסקה במשחק אל מספר שורת המקור ומיקום מדויק
במיוחד „סקירת המקור” ו„מיפוי פסקאות למספרי שורות מקור” הופכים את ה„הפיכה למשחק” לשקופה:
אתה לא חייב להתקדם רק בשכבת המשחק—אתה יכול בכל רגע לחזור למבנה המקור המלא ולראות בדיוק לאיזו שורה הגעת.
8. תמונות ממוזערות של שמירה ופרטי מצב קריאה—הכול נולד מסבבי מיקרו־כיוונון
בהמשך, מה שבאמת לקח זמן כבר לא היה פיצ’רים גדולים, אלא המון פרטים ש„המשתמש ירגיש מהם לא טוב במבט ראשון”, אבל לא בהכרח יוכל להסביר במשפט אחד.
למשל:
- בתמונה הממוזערת של שמירה האיור נחתך בראש
- תגיות ליד רגלי הדמות מרגישות כמו מידע דיבוג
- רמזי תיבת טקסט וידיות גרירה בולטים מדי
- HUD עליון קבוע גונב פוקוס
- כשיש כמה דמויות, ה־UI מפזר את קו הראייה של הקריאה
את הבעיות האלה כמעט תמיד לא פתרתי ב„להוסיף עוד פיצ’ר”, אלא בשליטה בקצב:
- מה צריך להיות מוצג קבוע
- מה צריך לדעוך
- מה צריך להופיע רק ב־hover
- מה צריך להופיע קצר רק בעת שינוי מצב
אחרי שמסיימים עם זה, התחושה זזה בצורה ברורה מ„דף ווב עם המון פונקציות” לכיוון „רומן חזותי שאפשר לקרוא בו בשקט”.
9. אימות אוטומטי הוא המפתח לאיטרציה מתמשכת בשלבים המאוחרים
בהמשך המשתמש ניסח את זה במפורש: „פשוט תמשיך לשדרג, לייעל ולאמת בעצמך את היכולות של השירות שלנו.”
אז משם לא רק שיניתי תצוגה, אלא גם השלמתי שרשרת אימות אוטומטית. בפרויקט יש סט בדיקות UI בסגנון Playwright, שמריץ שוב ושוב בדיקות על נקודות מפתח:
- האם כותרות מופיעות/נעלמות בזמן
- האם תיבת הטקסט ברירת־מחדל חוסמת את הבמה
- האם גרירה / סקייל / הצמדה עובדים כראוי
- האם מיקום וגודל מותאמים נשמרים ומשוחזרים
- האם ה־HUD העליון דוהה אוטומטית
- האם רמזי קריאה וידיות גרירה נחלשים בזמן חוסר פעילות
- האם מגירת שמירות, שמירה אוטומטית ותמונות ממוזערות של שמירה מהירה תקינות
- האם ריבוי דמויות חורג מהמסך בדסקטופ / מובייל
- האם לחיצה ארוכה במובייל להסתרת UI תקינה
- האם גלגלת ממשיכה להתקדם אחרי קיפול הבקרה
זה אומר שהאופטימיזציות בהמשך הן לא „לתקן דבר אחד ולהמר שמקומות אחרים לא נשברו”, אלא אפשר לתקן ולהריץ רגרסיה במקביל.
יכולת כזו חשובה מאוד בפרויקט UI אינטראקטיבי מאוד; אחרת בשלבים מאוחרים קל להגיע למצב של „תיקנת A, פיצצת B”.
10. המצב הנוכחי של הפרויקט
נכון לעכשיו, פרויקט ה־GALGAME של 《软件体的生命周期》 כבר מציע יכולת משחק וקריאות יחסית מלאה:
- שמירה על כל הטקסט המקורי, לא עיבוד תמציתי
- ממשק ראשי בסגנון GALGAME יפני
- חיבור איורי דמויות לכל הדמויות
- צבע טקסט שונה לכל דמות
- מעברי פרקים ותצוגת עמוד שם הספר
- תיבת טקסט: גרירה חופשית, סקייל ושקיפות
- מהירות טקסט תומכת בתצוגה מיידית
- לחיצה מחוץ לתיבת הטקסט להתקדמות
- גלגלת: הקודם / הבא
- ניגון אוטומטי, דילוג, הסתרת UI
- שמירה אוטומטית / מהירה / ידנית
- צפייה חוזרת, ניווט פרקים, סקירת מקור
- התאמה לדסקטופ / מובייל
- ליטוש רב־סבבי להפחתת „תחושת כלי”
- סקריפטי אימות אוטומטי לרגרסיה מתמשכת
אם בהתחלה היעד היה „להפוך קובץ md למשחק”, אז עכשיו ניסוח מדויק יותר הוא:
להפוך טקסט ארוך ומלא למערכת רומן חזותי שאפשר לקרוא, לשחק, לעקוב לאחור, ולהמשיך לללטש לאורך זמן.
11. החלק הכי מעניין בפרויקט הזה
מבחינתי, הדבר הכי מעניין בפיתוח הזה לא היה „שעשיתי עמוד GALGAME”, אלא שהתהליך כולו מדגים באופן מאוד טיפוסי דבר אחד:
כדי שמשהו ייראה כמו שצריך, לרוב זה לא קורה כי בגרסה הראשונה דוחפים את כל הפיצ’רים, אלא כי המשתמש מצביע שוב ושוב על „מה לא מרגיש נכון”, ואז סבב אחרי סבב מסירים את תחושת הזרות.
הפידבק של המשתמש היה מאוד ספציפי, והרבה ממנו לא היה „תשפר עוד קצת”, אלא:
- כאן זה חוסם את המסך
- למה זה נעול על רוחב מלא
- למה זה קופץ בכל משפט
- זה מציג רק חצי גוף תחתון
- למה בפינה שמאלית־עליונה זה לא נעלם לגמרי
- למה הגלגלת מפסיקה לעבוד אחרי קיפול הבקרה
דווקא הנקודות המאוד ספציפיות האלה של „זה נראה לא טוב” דחפו את הפרויקט מ„עובד” ל„נראה רציני”.
אם נמשיך בהמשך, כיווני ליטוש אפשריים בעיניי כוללים:
- סגנון איורי דמויות אחיד יותר
- בימוי פרקים עשיר יותר ומערכת BGM/SE
- מערכת CG / החלפת רקעים מלאה יותר
- יכולת תזמור סקריפטים חזקה יותר
- דרך אריזה והפצה רשמית יותר
אבל בסבב הנוכחי, זה כבר לא דמו—אלא פרוטוטייפ VN די שלם, שאפשר להמשיך לאטרץ לאורך זמן.
