📜 ⬆️ ⬇️

How to create a game engine for short stories in 3 days

One rainy day in St. Petersburg, my project in UE4 stopped loading, and because of this I wanted to make my own engine. And one story pushed me to make the engine just for stories. If you want to learn more and you are not afraid of goto, gosub and other horrors, welcome under cat.
KDPV




Table of contents






Act 1
It all started with the fact that after passing through the Nth story a friend recommended Katawa Shoujo to me. As it turned out the official version in the App Store is not and is not expected, only .ipa on w3bsit3-dns.com.
')
This same friend, knowing that I was trying to create a game for the third month, suggested that I port Katau to an iPad without a Jailbreak. The choice fell on smart BASIC, since I have been using this program for a year and a half and know the syntax of its internal programming language (also smart BASIC has an SDK for Xcode).

The archive was immediately downloaded with all the game files except text. But neither he nor I did not know that this would lead to the creation of his own engine for ease of development.

Act 2. Development


Act 2

1. Text


To start, I created a folder (spoiler).
Folders
/ Sprites
/ Event
/ Bgs
/ Music
/ Scenario
/ Scripts
/ Scripts / Ren_sB
/ Scripts / Ren_sB / Functions
/ Ui
/ Ui / main
/ Vfx

The Katawa Shoujo Port.txt file will load all scripts.
scenario$ = “Habr” {Scripts/colorcodes.txt} {Scripts/Ren_sB/render.txt} 

The colorcodes.txt file will contain RGB color names for the render, for example, take Shizune and its blue selection:
 data "","107","174","239" dim colors$(1,2) read colors$(color,0) 

The basic preparations have been made; now you can write a script to display the text. In Katava, as in any visual novel, the text is shown in the field, and above the text is written the name of the character on whose behalf the text.

The speak.txt script will be responsible for this.

To begin with, I registered the download of the bg-say.png sprite (field for replicas) and the playtime_cyrillic font in the file load.txt:
 font "Font/playtime_cyrillic2.ttf" load a$ sprite "bg-say" load "UI/bg-say.png" sprite "bg-say" resize 1024,205 sprite "bg-say" at 0,screen_height()-205 sprite "bg-doublespeak" load "UI/bg-doublespeak.png" sprite "bg-doublespeak" resize 1024,205 sprite "bg-doublespeak" at 0,screen_height()-205 sprite "ctc-strip" load "UI/ctc-strip.png" get sprite "ctc_strip" size w,h sprite "ctc_strip" resize w*1.28,h*1.28 sprite "ctc_strip" at screen_width()-w*1.28-15,screen_height()-52 sprite "ctc_strip" delay 0.05 


Then I decided to use the “|” sign in the script of the script as a separator for the command, goal of the command, secondary goal, action and attribute.

Text Display: “1 | Pers | Text”
 1||[, ] 


The render.txt file reads this command and redirects to the label alone.
render.txt
 graphics set toolbar off set orientation landscape file "Scenario/"&scenario$&".txt" readline hmm$ count = count+1 end = file_end("Scenario/"&scenario$&".txt") if end = 0 then goto count file "Scenario/"&scenario$&".txt" setpos 0 dim info$(count,5) for l=0 to count-1 file "Scenario/"&scenario$&".txt" readline line$ splite line$ to temp$,n with "|" for m = 0 to n-1 info$(l,m) = temp$(m) next m next l '  ,    ' show: for y = 0 to count-1 if info$(y,0) = "1" then gosub alone ... alone: {Scripts/Ren_sB/Functions/Speak.txt} return 


speak.txt
 sprite "bg-say" show name$ = info$(y,1) text$ = info$(y,2) '     ' for color = 0 to 6 if name$ = colors$(color,0) then r = colors$(color,1) g = colors$(color,2) b = colors$(color,3) endif next color '   ' field 1 text name$ at 20,575 size 600,40 ro field 1 back alpha 0 field 1 font color r/255,g/255,b/255 field 1 font name a$ field 1 font size 28 field 2 text render$ at 20,615 size screen_width()-20,130 ro ml field 2 back alpha 0 field 2 font color 1,1,1 field 2 font size 28 field 2 font name a$ '  ' for k = 0 to len(text$)-1 '     ' gosub 3 render$ = substr$(text$,0,k) field 2 text render$ pause 0.025 next k '    ' sprite "ctc_strip" show ! sprite "ctc_strip" loop gosub 1 sprite "ctc_strip" hide 


one
 1 x1 = touch_x(0) y1 = touch_y(0) if x1 > -1 or y1 > -1 then goto 2 slowdown goto 1 2 x1 = touch_x(0) y1 = touch_y(0) if x1 = -1 or y1 = -1 then return endif slowdown goto 2 


3
 3 x1 = touch_x(0) y1 = touch_y(0) if x1 > -1 or y1 > -1 then tapped = 1 endif if tapped = 1 then if x1 = -1 or y1 = -1 then tapped = 0 if len(text$) = 0 then k = lengthmax - 1 else k = len(text$) - 1 endif return else return endif endif return 


Result:

image

“But after all, in Katav two characters can speak at the same time!” There is a separate command for this: “2 | pers1 & pers2 | text1 & text2”:
2 | Hisao & Lilly | “Hello!” & ”Hello!"

Add to the render.txt line:
render.txt
 ... show: ... if info$(y,0) = 2 then gosub together ... together: {Scripts/Ren_sB/Functions/Double_Speak.txt} return 


Double_Speak.txt executes these commands:
Double_Speak.txt
 sprite "bg-doublespeak" show names$ = info$(y,1) '   ' nd = instr(names$,"&") name1$ = substr$(names$,0,nd-1) name2$ = substr$(names$,nd+1,len(names$)-1) texts$ = info$(y,2) td = instr(texts$,"&") text1$ = substr$(texts$,0,td-1) text2$ = substr$(texts$,td+1,len(texts$)-1) '     ' for color = 0 to 6 if name1$ = colors$(color,0) then r1 = colors$(color,1) g1 = colors$(color,2) b1 = colors$(color,3) endif next color for color = 0 to 6 if name2$ = colors$(color,0) then r2 = colors$(color,1) g2 = colors$(color,2) b2 = colors$(color,3) endif next color '  ' field 11 text name1$ at 20,575 size 300,40 ro field 11 back alpha 0 field 11 font color r1/255,g1/255,b1/255 field 11 font name a$ field 11 font size 28 field 12 text name2$ at 535,575 size 300,40 ro field 12 back alpha 0 field 12 font color r2/255,g2/255,b2/255 field 12 font name a$ field 12 font size 28 field 21 text render1$ at 20,615 size screen_width()/2-20,130 ro ml field 21 back alpha 0 field 21 font color 1,1,1 field 21 font size 28 field 21 font name a$ field 22 text render2$ at 535,615 size screen_width()/2-20,130 ro ml field 22 back alpha 0 field 22 font color 1,1,1 field 22 font size 28 field 22 font name a$ '     ' lengthmax = max(len(text1$),len(text2$)) lengthmin = min(len(text1$),len(text2$)) '  ' if len(text1$) = len(text2$) then for k = 0 to lengthmax-1 gosub 3 render1$ = substr$(text1$,0,k) field 21 text render1$ render2$ = substr$(text2$,0,k) field 22 text render2$ pause 0.025 next k endif if len(text1$) > len(text2$) then for k = 0 to lengthmax-1 gosub 3 render1$ = substr$(text1$,0,k) field 21 text render1$ if k < lengthmin then render2$ = substr$(text2$,0,k) field 22 text render2$ endif pause 0.025 next k endif if len(text2$) > len(text1$) then for k = 0 to lengthmax-1 gosub 3 render2$ = substr$(text2$,0,k) field 22 text render2$ if k < lengthmin then render1$ = substr$(text1$,0,k) field 21 text render1$ endif pause 0.025 next k endif '  ' sprite "ctc_strip" show ! sprite "ctc_strip" loop gosub 1 sprite "ctc_strip" hide 



Result:

image

On this the first day of development ends, and therefore the first part of my article ends. In the second part I will describe the second day, namely, I will add graphics (sprites, backgrounds and events) and music.

Thanks to all those who read to the end of the article. See you in the next part!

Source: https://habr.com/ru/post/274399/


All Articles