An engine that can be used to manage and play Visual Novels with limited interactivity. It supports a simple scripting language so you can control the story from within your XML file (which is the actual story).

Post tutorial Report content RSS feed How the shells work.

In this tutorial we'll cover what the shells are and how you could create them. With the engine you can also download 2 'shells' which are actually players. Where the engine actually does the grunt work, the shell provides the visuals to the user.

Posted by on - Basic UI/HUD

In this tutorial we'll cover what the shells are and how you could create them. With the engine you can also download 2 'shells' which are actually players. Where the engine actually does the grunt work, the shell provides the visuals to the user.

When programming in Flex, which is what the engine is written in (actually it's written in ActionScript 3, and Flex is just the regular Flash with some extra's), you can chose to either program for the desktop (AIR) or the web (FLEX).

Both AIR and FLEX applications do the same, AIR provides access to the system files of the OS it's running on. Other than that there is no difference, the engine also doesn't care if you use the AIR or the FLEX version.

So how does the shell work?

After deciding to go with AIR or FLEX you can include a library, which is a set of classes/functions/variables/... that are already programmed and ready for use. Just include the library of the engine and you're set to go.

Here's how you would do it:
Project -> Properties -> Flex Build Path -> select the Library Path Tab -> press the Add Library -> select the 'vnEngine' library.


As an alternative you could include the SWC of the engine. Which is a compiled version of the library.

So now that the shell has included the library we've got access to all the functions that the engine provides. All it now has to do is tell the engine to start loading the engine and visualizing every frame.
How does the shell start the story?
In my basic AIR shell it loads the story when the application is initialized:

private function initApplication():void {
	initializeWindowToolbar();
	
	tryOpenXML();
}

In this initialize method it does 2 things, it initializes the window tool bar. Which is just some extra code that handles the window skin.

the 'tryOpenXML()' function tries to load the given XML and if it does it tells the engine to start loading by calling this function:

public function storyLoadXMLF(path:String):void {
	Engine.addEventListener(Engine.EVENT_ASSETS_LOADED, storyAssetsLoadedF);
	Engine.addEventListener(Engine.EVENT_FRAME_UPDATED, storyFrameUpdatedF);
	Engine.addEventListener(Engine.EVENT_END, storyEndOfStoryF);
	Engine.processXML(path);
}

This function tells the engine that it wants to listen to the available events:

  • All assets loaded
  • Frame updated
  • Story ended

And finally tells the engine to load the story located by the path variable.
So now, behind the scenes, the engine starts loading the story and assets.

Now when all the assets are loaded it will initialize the shell and show the cover image.
When the user clicks on the cover image it will continue with the story.
The engine tells me the frame has been updated!

This means that the dialog or the frame has changed, basically SOMETHING changed and now the shell should update the visuals. Here's the code for updating the visuals:

private function shellUpdateFrameF():void {
	shellBackImage.source = Engine.getBackImage();
	shellFrontImage.source = Engine.getFrontImage();
	
	shellDialogText.htmlText = Engine.getDialogText();
	shellDialogCharacter.text = Engine.getDialogCharacter();
	
	shellCreateAnswersF();
}

All the shell does is retrieve the latest front and back image and changes the dialog. The dialog, of course, needs answers but they are a bit more complicated so they are inside a different function:

private function shellCreateAnswersF():void {
	var answ:Array = Engine.getDialogAnswers();
	
	shellAnswers.removeAllChildren();
	
	for (var i:int = 0; i < answ.length; i++) {
		var cont:VBox = new VBox;
		cont.styleName = "shellAnswer";
		var txt:Label = new Label();
		txt.text = answ[i];
		txt.addEventListener(MouseEvent.CLICK, shellSelectAnswerF);
		txt.styleName = "shellAnswer";
		txt.name = i.toString();
		cont.addChild(txt);
		
		shellAnswers.addChild(cont);
	}
}

How the shell does this, creating the answers, doesn't matter all it needs to do is tell the engine what answer is actually selected:

private function shellSelectAnswerF(e:MouseEvent):void {
	Engine.answerSelected(int(Number(e.currentTarget.name)));
}

These functions are run over and over again until the story has ended and when that does the shell displays the credits:

private function shellLoadCreditsF():void {
	var c:ArrayCollection = Engine.getCredits();
	for each (var person:Object in c) {
		shellCreditsNames.text += person.name + ": " + person.task + "\n";
	}
}

And that's it!

So now you can change or upgrade the provided shells or use this documentation and maybe the shells themselves as example and create your own. If you do want to create your own shell I recommend reading up about the engine.

Thanks.

Post a comment
Sign in or join with:

Only registered members can share their thoughts. So come on! Join the community today (totally free - or sign in with your social account on the right) and join in the conversation.

Platforms
Windows, Mac
Company
IntoGames
Contact
Send Message
Release date
Engine watch
Start tracking
Tutorial
Browse
Tutorials
Share
Related Engines
Visual Novel Engine
Visual Novel Engine Creative Commons
Related Groups
IntoGames
IntoGames Developer & Publisher