SkillAgentSearch skills...

VANE

Visual Novel Engine for SEGA Mega CD in BEX

Install / Use

/learn @mojontwins/VANE
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

VANE - Visual Adventure Novel Engine

VANE is a Visual Novel engine for SEGA Mega CD (we have in mind porting it to other weird systems such as PC XT/CGA, for example). It's based upon several subprograms which are chained together to create a game. There's one module missing: a Snatcher style battle engine which I never finished.

VANE was created in 2015 as a vehicle to create remakes of some old visual novels for MSDOS made by na_th_an circa 1994-1995. In mid 2015, Jon Cortazar from Relevo helped us with planning and design, making the engine much more flexible and powerful.

You will need BasiEgaXorz. Go get it from http://devster.monkeeh.com/sega/basiegaxorz/ . Read some docs and get a hello world program running from a cart in your emulator before even attempting to read this doc.

Also, you should learn a bit about how Mega CD works. There's a data track on the CD, which is divided in "clusters". Clusters are numbered chunks of data within the data track which can be individually loaded by the Mega CD. We'll be talking about clusters a lot, so be sure you understand the basics.

Visual Novels are created assembling assets in clusters. Most of your clusters will be image data or script data. Together, a image data cluster and [at least] a script data cluster will make a "chapter". Each cluster is loaded in the Mega CD's RAM space, so the length of your "chapter" is somewhat limited. In each "chapter" you have 120K for images and 4K for scripting. A VANE game is divided into "chapters".

Subprograms

As mentioned, VANE is based on several chained subprograms. Such subprograms reside in individual clusters in the CD. A minimal VANE game would contain three subprograms:

  • main.bex - This is the main program, which initalizes stuff and jumps to the menu (if present) or directly to the engine (otherwise).
  • menu.bex - This should contain your main menu / title screen / etc. You have to code this in BEX yourself.
  • vane.bex - This is the engine itself, which runs the defined "chapters" in order.

The engine supports two extra programs with almost no modification:

  • gameover.bex - You know.
  • ending.bex - Yeah, you know.

You can add your own custom subprograms. There are 32 slots for defining custom subprograms. The first five slots are reserved for the above mentioned subprograms and should not be altered.

In a Mega CD, programs are loaded from clusters. There's a 32 byte reserved memory section used to define which cluster contains each of the defined subprograms. If the value stored is 0, it means that such slot contains no subprogram.

main.bex

BEX is a tad strange. The implementation of Mega CD support is a bit sketchy, but it gets the job done. Basicly, you have a main subprogram which BEX will stuff in cluster 1. BEX runtime itself is stored at cluster 0. When you run the CD, BEX runtime will jump to cluster 1 after initializing some stuff.

This main subprogram is a bit special - besides actual code, it contains compiler directives which instruct BEX about which additional clusters it should add to the data track in the CD. This is performed via addscd commands.

In VANE, main.bex is used to load binaries and programs into clusters, configure the program slots and other options, and then run the menu slot or the engine slot.

Slots-clusters mapping

The first section in main.bex contains POKEs to map suprogram slots to clusters. As mentioned, the five first slots are reserved for menu, engine, battle, game over and ending. Slots table is located at memory addresses $FFFF00 - $FFFF1F inclusive. A typical, minimal slot mapping would be:

    ' Configure the location of subprograms here.
    ' Poke a 0 to deactivate.
    
    Poke &HFFFF00, 2                    ' MENU.SCD
    Poke &HFFFF01, 3                    ' VANE.SCD
    Poke &HFFFF02, 0                    ' BATTLE.SCD
    Poke &HFFFF03, 0                    ' GAMEOVER.SCD
    Poke &HFFFF04, 0                    ' ENDING.SCD

As mentioned, a 0 means "not present". VANE will ignore default slots if a zero is found. The battle system is still not implemented nor hooked, by the way.

Cluster loading

The next section in main.bex is used to tell BEX which binaries / compiled subprograms it should add to the data track in the CD. This is done via addscd commands. Note that addscd only takes a file name as a parameter, so you should keep track of the cluster number yourself.

As we mentioned before, BEX's runtime is stored at cluster 0, whereas the main subprogram in main.bex will be stored at cluster 1. So the first addscd command you issue will load the binary at cluster 2, the next at cluster 3, and so on. Do yourself a favour and take note of which cluster contains which binary.

The subprograms you want to add to your CD data track must be compiled first. Open them in BEX and compile them to SCD. Be sure to store all your SCDs together alongside the main.bex file. Once you have them in SCD you can add them using addscd. On a minimal VANE project, as described, you should have menu.scd (from menu.bex) and vane.scd from vane.bex ready. Then load them up:

'' Cluster loading...

    addscd menu.scd                     ' 2
    addscd vane.scd                     ' 3

Note how I keep track of which clusters are those binaries being loaded to using coments. Note also how the cluster numbers are the same POKEd to the $FFFF00 - $FFFF1F range in the first section of main.bex.

General asset loading

The next section will load some binaries used for general assets. In the barebones project included with this distribution, I load two pairs of charset-palette definitions. I use the first pair in the menu and the second pair in VANE.

    addscd bin\charset-menu.bin         ' 4
    addscd bin\charset-menu-pal.bin     ' 5
    
    addscd bin\charset-vane.bin         ' 6
    addscd bin\charset-vane-pal.bin     ' 7

We also use this section to add a cluster with custom sounds we can fire up from the scripts. Please read the section Sounds cluster for more info:

    addscd bin\sounds.bin               ' 8

Chapters loading

Your game is split in chapters, which are [in their simplest form] pairs of clusters containing image data and script data. In the engine (see later), each chapter is refered by the cluster number of its image cluster (the related script cluster[s] comes next), so related image and script clusters should be loaded together, image cluster first.

The next part of main.bex is used to load up the clusters of each chapter in the game. Our bare bones proyect only has two chapters:

    ' The game
    
    ' Chapter 1
    addscd bin\im00c.bin                ' 9
    addscd bin\sp00c.bin                ' 10

    ' Chapter 2
    addscd bin\im01c.bin                ' 11
    addscd bin\sp01c.bin                ' 12

The last thing main.bex does is executing menu.scd if its slot #1 does not equal 0 but a cluster number, or vane.scd directly, otherwise.

menu.bex

You can use menu.bex for many things. For example, you could store several visual novels in the same CD and launch the engine starting in the correct "chapter" for each novel, or implement a password option for jumping directly to certain chapters in your novel... You name it.

menu.bex will present a menu (or just a splash screen), it will POKE some values in the engine configuration memory area, then fire up vane.scd.

Engine configuration memory area

The engine configuration memory area starts at $FFFF20. It is used to configure several aspects of the engine, such as from which chapter it should start, viewport position, text window size, menu position, etc.

Chapter Number

    Poke &HFFFF20, chapter 

When run, the VANE engine will start executing from the chapter number stored at $FFFF20. As explained later, vane.bex should contain a table specifying the cluster where each chapter resides.

Flag 127

    Poke &HFFFF21, value 

The VANE engine has up to 128 integer flags. On startup, the value at $FFFF21 is copied to the last flag (#127), so you can act accordingly. This can be used for all sorts of things related to controlling how your game behaves from the menu.

Command and Next Address in Script

    Poke &HFFFF23, 0            ' Run chapter from the beginning.
    Poke &HFFFF24, 0
    Poke &HFFFF25, 0

Those addresses are used internally so a script can execute a BEX subprogram and resume execution once it ends. See later for more info on 'external subprograms'. Just set them to zero.

Language modifier

    Poke &HFFFF26, language

We mentioned that each chapter was a "pair" of image data and script data. This is not completely true, as each chapter is in fact a "tuplet" of clusters, the first being a common image data cluster and the rest equivalent script clusters in different languages.

Imagine you want to create your novel in English and Spanish and you load your chapters as triplets of image cluster, script cluster in English, script cluster in Spanish. With that configuration, poking "0" to $FFFF26 would make VANE always run the English language scripts, and poking "1" would make it run the Spanish language scripts.

In other words, if chapter N is stored from cluster M onwards, then cluster M is the image cluster, and cluster M + 1 + language_modifier is the associated script which will be run.

For single language games, just poke a 0.

Top of the screen

    Poke &HFFFF27, 1

This is the character line from which pictures will be displayed. If you use a title bar, for example, poke an 1.

Show title bar

    Poke &HFFFF28, 1            ' Show 
View on GitHub
GitHub Stars14
CategoryDevelopment
Updated5d ago
Forks5

Languages

Assembly

Security Score

75/100

Audited on Apr 2, 2026

No findings