anybody familiar with the story script in Rocket Viper?

  • Thread starter Thread starter doranikofu
  • Start date Start date
D

doranikofu

Guest
Rocket Viper has a story script that allows saving all the dialogs in txt file. This saves a lot of resources if the game has lots of storylines. The most impressive thing is that it supports Chinese characters (set through level difficulty level at beginning of game, 0=english 1=chinese).

I was looking at the project(RV2 v2.4) but still cannot understand how it fully works.

> Lines written in txt file, starting with character name and words to display. Script loads the name and avatar (based on name)
sample dialog "xiang1.txt"
Code:
Girl		1	You_villain!!		I_won't_let_you_get_away!
Kim		0	V_._._._villain?	You're_talking_to_me?
Terry		0	She's_talking_to_you,Akuma.
Akuma		0	Humph!
end

> spawn a entity named story in the stage, alias specifies the filename of the dialog txt to load. For example, the dialog above would be
Code:
spawn story
alias xiang1
at 0

the story entity is defined with empty image
Code:
name		story
type		text
subtype		noskip
shadow		0
health		1
animationscript data/scripts/story.c

anim	idle
	loop	1
	delay	10
	frame	data/chars/misc/empty
	@cmd	talk
	frame	data/chars/misc/empty
anim	freespecial
	loop	1
	delay	5
	frame	data/chars/misc/empty
	delay	4000
	@cmd	sendMsg
	frame	data/chars/misc/empty

> the script file I could not understand how it works. I can get how the script it loading the player name, avatar facing direction, lines, and playing effects from txt file. But I can't track down to find the script to actually display all the contents (like dialog box, etc) Are some of the commands build-in? I could not find much from the referenced script files in the #include
Code:
#include "data/scripts/define.h"
#include "data/scripts/common/playsnd.c"
#include "data/scripts/common/iscn.c"
void getCname(void name)
{
	void cname;
	if (!isCN()) return name;
	if(name=="Sarah"){
		cname="莎拉";
	}else if(name=="Shiki"){
		cname="色";
	}else if(name=="Ken"){
###------------omitted for brevity, for name conversion ------------------
	}
	return cname;
}
void sendMsg()
{
	//name direction msg msg1 pro width
	void	self	=	getlocalvar("self");
	void	filenumber	=	getlocalvar("fh");
	void	name	=	getfilestreamargument(filenumber,0,"string");
	void	dir		=	getfilestreamargument(filenumber,1,"int");
	void	msg2	=	getfilestreamargument(filenumber,2,"string");
	void	msg22	=	getfilestreamargument(filenumber,3,"string");
	void	pro		=	getfilestreamargument(filenumber,4,"string");
	void	sound;
	if(msg22==NULL())
		msg22="_";
	if (name=="end"){
		endStory();
	}else if(name=="_sound"){
		playSound(msg2);
		filestreamnextline(filenumber);
		updateframe(self,0);
	}else if(name=="_white"){
		setindexedvar(WHITE,1);
		filestreamnextline(filenumber);
		updateframe(self,0);
	}else if(name=="_normal"){
		setindexedvar(WHITE,-1);
		filestreamnextline(filenumber);
		updateframe(self,0);
	}else if(name=="_music"){
		playmusic(msg2,1);
		filestreamnextline(filenumber);
		updateframe(self,0);
	}else if(name=="_stopmusic"){
		fademusic(1);
		filestreamnextline(filenumber);
		updateframe(self,0);
	}else{
		if (name=="_player"){
			void vSelf = getplayerproperty(0, "entity");
			if (vSelf==NULL()){vSelf=getplayerproperty(1, "entity");}
			if (vSelf==NULL()){vSelf=getplayerproperty(2, "entity");}
			name = getentityproperty(vSelf,"name");
		}

		if (pro=="" || pro==NULL() ||pro=="_"){pro=name;}

		setglobalvar("story.msg1",msg2);
		setglobalvar("story.msg2",msg22);
		name=getCname(name);
		setglobalvar("story.msgName",name);
		setglobalvar("story.msgPro",pro);
		setglobalvar("story.dir",dir);

		filestreamnextline(filenumber);
		setindexedvar(story_switch,1);
	}
}

void talk()
{
	void self = getlocalvar("self");
	char folder=getentityproperty(self,"name");

	setindexedvar(STORY_ENT,self);
	setindexedvar(PAUSE,0);
	if (folder!="story"){
		setlocalvar("fh",openfilestream("data/story/"+getPath()+"/"+folder+".txt"));
		changeentityproperty(self, "animation", openborconstant("ANI_FREESPECIAL"));
	}
}

void playBgm(char bgm){
	playmusic(bgm, 1);
}

void endStory()
{
	//if there's no backfile then disable credit scroll screen
	if(!getglobalvar("story.backfile"))
	{
		setindexedvar(PAUSE,0);
		setindexedvar(story_switch,NULL());
	}
	//
	setindexedvar(STORY_ENT,NULL());
	killentity(getlocalvar("self"));
}

I think it would be cool if there is a template project with only the essential things to make this work. This will give a lot of versatility for different language support in game. I tried to load those files into my project but I definitely missed something. Whenever the story entity spawns the level freezes (text entity, character not moving but can pause game with start button and exit, no error in log).
 
I digged up the script files and make it work for English dialog at the moment, still working on loading Chinese characters.

To make it work there are a few essential script files (based on RV2 v2.4)
custom scripts (directly copy and make sure the depend files are copies as well):
bistory.c
screen.c
story.c
/common/iscn.c
/common/playsnd.c
define.h

The global scripts required (only need specific functions loaded into the "main" function):
keyall.c -> only need dialogSkip function, copy it and put it in the main()
updated.c -> only need to load story() when "in_level"。 I also copied pause and spawnEnt just in case, I have not tested further

In addition, you will need to make a text entity "Story", maybe "Pause" as well. I have not got time to check. Then in level, spawn Story with alias of the dialog file to load.
Of course you need to make sure all the dialog txt and profile pics are placed (follow the format in RV game)

Works for me in English. Chinese is showing color blocks but not loading character. I noticed that RV loads fonts under Sprites/Font# folders, not directly under Sprites folder. I have not found a script that defines this yet, but maybe someone else has an idea.
 
You're not the only one who had done tinkering of Rocket Viper 2.4 as well. I did so too, and guess what ...

I wanted to see how he did the story script as well, it's hard because one, some of the important comments and terms are Chinese and second, there's too much calling of various stuff that's confusing. The reason the animated title was just easily tackled was because of the fact that most people used the loading bar similar to Rocket Viper 2 and when I saw them altogether, it became easier to crack it and tried for myself.
 
It's been a long time since I dug into that code but I used a modified implementation of Volcanic's RV2 dialog script in my mod. You can see it in "action" in the last demo I posted yesterday. I didn't try to use multiple langages though.

Coding wise it's quite a mess but it might indeed be interesting to create an abstract dialog module (that works similar to this script) which could be easily used in future mods.

 
Apparently Volcanic wants to make a parser that is read via script. There are actually three different scripts he used:

script.c - general dialog script.
scriptg.c - full screen dialog with picture for scrolling.
scriptln.c - scrolling dialog with credits.

Both scriptg and scriptln only have one function which is show, but the similarity ends there.
The show utilized by scriptg:
show (back, spd, storypic, picheight);
back - static background of the credits (needs to be in script since it's rendered along wiht the scrolling picture.
spd - speed of the scrolling picture
storypic - the moving scrolling picture itself

The show utilized by scriptln though is less involved, but it reads a specific text file, we can fix that.
show(a, back, spd)
a -
back - the static background of the credits
spd - speed of the scrolling text.



What I understood for the dialog script is this:

* which is either the same name as the {name} or given in {pro}



BASIC TEXT:
make a noskip entity and use story.c as your animationscript

{name} {dir} {message} {message2} {pro}

name - name of the character.
dir - the direction that the character is facing. (probably defaults to 1 as some of the other dialogs don't have it as well)
message - the message that the character wants to say
message2 - the second line message for the dialog
pro - the avatar of the character. If undefined, uses the {name} as image.

Names that you can use for {name}:
_sound - This will play a sound file. {message} will serve as sound file

_white - I don't know what this does.

_normal - Negates the function of _white, I guess (actually it just sets the indexed variable WHITE to -1 with _white of course sets it to 1, has something to do probably with screen.c?)

_music - Changes the music. {message} will serve as location of music

_stopmusic - Stops the music.

_player - Get's the current player's name, appropriately displaying it as the name.

Note that on all of these, dir must be set to 0 or else, error ensues.

end - This will end the dialog, allowing it to be removed. You don't need dir here, since it's in the end of the file, the last string to be detected and therefore will not error. Technically, it calls endStory().



CREDITS (or anything scrolling):
make a scene and make a c file just for your scene to be set as updatedscript.
in the C file, include storyln.c

{TEXT} {FONT} {X}
TEXT - the text you want to display
FONT - Font to be used. This was preformatted in storyln. Apparently setting to 1 makes the font as
X - The x position. Note that if left blank, this will set it to default value. Used in the credits to center the text.

_ - one line
___ - break (similar to end in dialog)

That's what I recovered so far. Sorry, it's kind of long, but it's for the benefit of the community nonetheless.

If I have the time, I might make a more cleaner version of these scripts so that anyone can use.
 
thanks for the info. I think I'm understanding it correctly.

I just figured out how to make the Chinese working although I cannot understand why.
Basically I searched "font" in all the files in the RV project and I found that there is one line in the menu.txt
"fontmbs 1 1 1 1 1 1 1 1"

I did not find in the manual explaining what this is doing but once I have this, my project starts to load the fonts under the Sprites/Font# folder and it also loads the Chinese characters. lol
 
doranikofu said:
thanks for the info. I think I'm understanding it correctly.

I just figured out how to make the Chinese working although I cannot understand why.
Basically I searched "font" in all the files in the RV project and I found that there is one line in the menu.txt
"fontmbs 1 1 1 1 1 1 1 1"

I did not find in the manual explaining what this is doing but once I have this, my project starts to load the fonts under the Sprites/Font# folder and it also loads the Chinese characters. lol

fontmonospace {1} {2} {3} {4} {5} {6} {7} {8} # {1} refers to font.gif, {2} refers to font2.gif and so on. 0 = Variable width font (default). 1 = Monospaced.
 
nsw25 said:
someone needs to make this sort stuff easier to impliment in Openbor...

Once the system is installed it's not that difficult to use really. But surely we could use a GUI editor to generate dialog files though. I'll probably create one some day, when I'll start writing many scenes.
 
I'll help with making a better script (probably others want to join in too) compatible for your GUI that has the same capabilities as Volcanic's one only far less complicated.
 
White Dragon said:

In the OpenBOR code, there is such thing as fontmbs, similar to fontmonospace, but is routing on a different variable than the monospace variable. Will search the SVN for when did this feature started.

It's added by utunnels in revision 3624:
Multi-byte string support for font functions.
Add a new command fontmbs in menu.txt to flag this change.

It's multi-byte support. This extends the support from the standard 144 glyphs to 256 glyphs or supports unicode, I think, that I can't say. This needs more research though.

EDIT: I saw that what he encoded is already Unicode, probably this extends unicode support for OpenBOR.

And the params is 0 is disable multi-byte and 1 enable multi-byte. Apparently, the code is probably documented in Lavalit before I think as you can't find fontmbs here in the forums (as it's undocumented).
 
Thanks CRxTRDude, this will be helpful. Saddly, Volcanic make some cool things, but its very hard to be reached.
Btw, Lagarto has a different text script, with small portraits too, using variables at the stage header.

And there is the option from White Dragon. Its at the tutorials section.
 
Well, for one thing to say to all this, if only utunnels would add more significant info regarding his changes, it would be much easier. He does put info on what it is, but apparently implementing it is hard. fontmbs gives lots of possibilties such as multi-language games, problem is how to use it and RV2 is evidence on how to do it, but again, is cryptic. We can either consult the one who made it, which I don't know if we could contact or ask someone who knows more deeper understanding on what it is (like DC or Plombo).
 
nsw25 said:
someone needs to make this sort stuff easier to impliment in Openbor...

Like several before have said, this is not the purview of OpenBOR itself.

Story systems are a design time feature, not run time. There's never any reason to stick a pet rock like this onto the engine when it already has the capability to run the scripts. We just need tools to help create those scripts (think of them as plugins if you want), and that is starting to take form.

DC
 
That's where scripts come in and do the specific jobs that we want to place in our game. The engine gives us the tools, the possibilities are limited by the capabilities and skills of the modder as well as the imagination (not being rude, but you get the point.)

BTW, DC, can you guess about how the fontmbs worked and what languages/encodings it supports and how to implement it? I was looking at RV2, saw how Volcanic laid out the fonts, the folder's like this:

00 - regular
b0 - chinese subset of 256 characters
b1 - same as b0
...
c1
...
d1

They looked like hex numbers though, they run from b1-bf and so on.

I know that it's just expanding the 'max' value of the fonts from the usual to 256, am I right?
 
CRxTRDude said:

I don't have the first clue about the font system because I've never taken so much as a glance at it. I'm going to be wheels up for Whistler Canada tomorrow and gone through the week - will be able to post, but probably not code much. I'll see what I can dig up when I get back if someone doesn't beat me to it.

DC
 
Apparently Plombo is busy IRL so I guess it's either you or someone else.  ;)

And be safe there at Canada DC  :D You'll need the break (if break is what you're there for)
 
Back
Top Bottom