שלוש דרכים שבהן ראיתי בנייה חובבנית של משחקים משתבשת, וכל אחת מהן מלמדת אתכם איך נראית ההגדרה הנכונה על ידי כך שהיא משאירה אחריה בלגן.
טעות ראשונה: לסמוך על הדפדפן לשמור את הניקוד
הכי נפוצה, והכי ניתנת להימנעות. מישהו בונה משחק עם לוח תוצאות, מחבר WebSocket לחלקי המולטיפלייר, ונותן ללקוח לחשב את הניקוד הסופי לפני שליחתו לשרת ב-POST. בלי שום אימות בקבלה. ראיתי את זה קורה במו עיני — לקח לשחקן משועמם בערך ארבע דקות לפתוח את DevTools, למצוא את לשונית הרשת, ולהתחיל לשלוח ניקודים בני תשע ספרות. לא כי הוא היה האקר. כי המשחק נתן לו את העט וביקש ממנו לבדוק את המבחן של עצמו.
התיקון לא חכם, הוא פשוט מייגע: לעולם אל תסמכו על הלקוח, נקודה. כל פעולה נבדקת מחדש בצד השרת, כל טיק פיזיקה מותאם למה שהשרת חושב שנכון, ואתם סופגים את עלות הזמן של סבב מלא במקום לרנדר מקומית ולקוות שאף אחד לא יבדוק מתחת למכסה. בגלל זה סמכות בצד השרת אינה סעיף נחמד-אבל-לא-הכרחי כאן — היא הרף. משחק שאפשר לנצח דרך קונסולת הדפדפן נחשב שבור, באותה חומרה של קריסה, כי מבחינה פונקציונלית זה בדיוק מה שהוא.
טעות שנייה: אלמנט canvas וצפצוף, שקוראים לו משחק
זה מדגים יפה ומתפרק אחרי תשעים שניות של משחק אמיתי. כמה מעברי CSS, בדיקת התנגשות, גל סינוס שממלא מקום של קול אגרוף — זה נראה טוב בהקלטת מסך, ואז השחקן האמיתי הראשון אומר שהתנועה מרגישה לא נכון ולא יכול להסביר למה. זו הפיזיקה. קוד ״אם יש חפיפה, קפוץ״ שנכתב ידנית אף פעם לא מקבל מסה, חיכוך ותגובת התנגשות בצורה מדויקת, והשחקנים מרגישים את הפער גם כשהם לא יכולים לשים עליו שם.
בנייה של משחקים כאן משתמשת ברינדור אמיתי של מנוע במקום זאת:
- פיזיקה ורינדור — three.js עם סימולציית פיזיקה אמיתית עבור דברי הרשת, Unity 6 אמיתי במעבדה עבור כל דבר כבד יותר.
- אמנות — מגיעה מבמאי העיצוב, לא מחבילת נכסים מוכנה מהמדף.
- אודיו — כלים דגומים, לא אוסילטור שעושה חיקוי הכי טוב שהוא יכול לצליל צעד.
ההסבר המורחב לכך שזה לא אופציונלי נמצא במנועים אמיתיים, בניות אמיתיות.
שרשרת המאמתים תופסת את הכשלים שצילום מסך לא יתפוס:
- לוחצת על מקשים.
- בודקת שהניקוד באמת משתנה.
- מאזינה לפלט אודיו.
נשמע כמעט בסיסי מכדי להיות שימושי, עד שמבינים כמה בניות מרנדרות פריים ראשון מושלם ואז נתקעות בשקט כי מאזין אירועים אף פעם לא חובר. תמונה סטטית לא יכולה לספר לכם את זה. מאמת שצריך לשרוד שלושה סבבי משחק כן יכול.
טעות שלישית: לגרום לחבר שלכם להריץ שרת כדי לשחק במשחק שלכם
פרוטוטייפים טובים של מולטיפלייר מתים בשלב הזה כל הזמן — לא כי המשחק גרוע, אלא כי "קודם תתקין npm install לשרת, ואז תגדיר שלושה משתני סביבה האלה" זה יותר מדי לבקש ממישהו בערב שלישי. בניתם משהו כיפי וקברתם אותו מאחורי מדריך התקנה.
משחקים לשחקן יחיד כאן מתפרסמים באותו אופן כמו כל אתר — לחיצה אחת לתת-דומיין חי, בלי תהליך נפרד ללמוד. מולטיפלייר שונה כי יש תהליך שרת אמיתי שצריך להישאר פעיל איפשהו, אז אלה מתפרסמים לדף משחק ציבורי עם אחסון מטופל עבורכם. כל הרעיון צר: "רוצים לשחק?" צריך להיות URL שמודביק בצ'אט קבוצתי, לא README.
מה נשאר לכם מהניגוד
שימו לב למה שחסר בכל שלוש הטעויות שלמעלה: שני שחקנים מקומיים. מקלדת אחת, שני אנשים, בדרך כלל WASD מול מקשי חצים, מרפקים נתקלים — זה המצב שאנשים מזלזלים בו כי אין לו בעיית הפצה בכלל. בלי קישור, בלי שרת, בלי חבר שצריך ללחוץ על משהו ב-11 בלילה. רק מישהו שיושב לידכם ושלושים שניות של "לא רגע, אתה שחקן שתיים, תשתמש בחצים".
| שני שחקנים מקומיים | מרובי משתתפים מקוון | |
|---|---|---|
| הכנסת משתמשים | "לא רגע, אתה שחקן שתיים, תשתמש בחצים" — שלושים שניות | התאמת יריבים, מסכי "ממתין ליריב" ריקים |
| הפצה | אפס — בלי לינק, בלי שרת, אף אחד לא צריך ללחוץ על משהו בשעה 11 בלילה | דורש דף משחק ציבורי ומישהו אחר מחובר באותו זמן |
| המרה | כמעט 100% — החיכוך היחיד הוא "תסובב את הכיסא" | נוטש תוך כדי המתנה ליריב |
בניות ה-air-hockey ומשחקי הזירה בגלריה נשענות בדיוק על זה.
חברו יחד את שלושת התיקונים — סמכות בצד השרת, מנועים אמיתיים, דפי משחק ציבוריים מתארחים — יחד עם היתרון המובנה של שני שחקנים מקומית, ותקבלו את הטווח האמיתי שהמערכת הזו תומכת בו:
- שחקן יחיד — קו הבסיס.
- שני שחקנים מקומית — הניצחון החינמי.
- ריבוי משתתפים מקוון — בנוי לשרוד נער משועמם עם DevTools פתוח.
כל משחק נאסף בספריית "המשחקים שלי" עם סטטוס פרסום לכל משחק, כך שלא צריך לחפש בשרשורי צ'אט ישנים כדי למצוא איזו בנייה הייתה הטובה. ואם ארזתם משהו לאנדרואיד, זה ממשיך ישירות אל מסלול החנות במקום להתחיל תהליך נפרד מאפס.



