Welcome to TiddlyWiki created by Jeremy Ruston, Copyright © 2007 UnaMesa Association
!Get wet! Learn vx!
Think back to your childhood for a moment. So many fond and cheerful memories. The laughters and friendships are still warm to think about today.
You had someone you looked up to when you were a child. Someone you //respected//. They defined every detail of how you became who you are today. You learned valuable life lessons and thought of them as a hero. ''Who was this?''
''Was it you?'' I mean, you were pretty exceptional. ''A total coolcat.'' A classy //and// enticing legend on the playground. A //lord// of conversation. A master of brilliant ideas. Just charming. People were //drawn// to your greatness.
But let's not get too cocky here. We //know// it wasn't you.
''Maybe your friends?'' Yeah, totally awesome, the greatest crowd you've ever been with. But let's face it, you were kids. You couldn't have learned many life lessons from them. That is, until way later on in life, when they all became a homeless alcoholics who tell people the government is putting fluoride in their tap water. ''You didn't want to be them'' when you were a kid, and certainly not now as an adult.
Think a little more //reasonable// here.
''How about your family?'' Well, they must have rocked! I mean, I'm sure most of the charm you acquired in your early years was likely //hereditary//. They raised you, and taught you everything you knew! Truly legendary.
@@font-size(2em)://Bzzzzt.//@@
Okay, time's up.
Think a little deeper. ''In the ocean'', that is. Beautifully crafted, simple and distinct. ''A starfish!'' But this wasn't just any starfish. It was a heroic legendary critter with a //dark// and //mysterious// past!
Behold, our hero ''Starfin''!
[img[Starfin|tutimg/starhero.png]]
You, in fact, respected this starfish so much that you decided he should be the ''lead character'' for your upcoming revolutionary ''strategy game'' set in a chaotic and surreal ''underwater universe''.
Think back to ''Dr. Seuss''. You remember //him// at least, right?
@@font-size(2em)://One fish, two fish//
//Red fish, blue fish//@@
[img[Starfin|tutimg/redfishbluefish.png]]
@@font-size(4em):Well, these fish are ''at war''!@@
Now witness the greatness that will be this underwater strategy game, all documented here! Prepare yourself for this; a bubbly and breathtaking dive into how to use the wondrous vx utility.
!Table of Contents
*[[Phase 1: Let's Learn Lua!|GetWetPhase1]]
!Phase 1: Let's Learn Lua!
''Our dream game has been planned.'' An underwater strategy game starring a //mysterious// and all-around //heroic// starfish protagonist named ''Starfin''.
But now we need to start making magic happen. Except since magic //doesn't exist//, we go for the ''next best thing'', that also requires high ''Intelligence'' and ''Wisdom''. We call this magical thing ''scripting''. LuaVerge uses a scripting language called Lua, which you can read about elsewhere. vx is a bunch of nifty additions to LuaVerge that look pretty.
Lua scripts are extremely useful and cool! But they might be hard to read and understand if you've never seen them before. So let's explain the various pieces of language!
!!Variables, Comments and Number Operations
Variables can have any name consisting of letters, cute little underscores and happy digits. For example, {{{x}}},{{{ y}}}, {{{x2}}},{{{ nachos45}}} or {{{octopus_leg_count}}}!
Think of variables as a way of remembering information! If you give something to the computer it normally only looks at once and then forgets about it. With variables, you can talk about something you did earlier, and Lua will totally remember!
You're given the equivalent of "Hey can you remember that an octopus has eight legs?" And Lua will be all, "Hey yeah, I can do that!". Provided you give declare it a variable:
{{{
octopus_leg_count = 8
}}}
See how simple that was? We use the equals {{{=}}} sign for ''setting a variable''.
And we've magically made a Lua variable. We can now use this little trivia to come up with a formula for how many legs the legendary quadrapus would have. And a few of their close cousins too!
{{{
octopus_leg_count = 8
-- The quadrapus has half the number of legs an octopus has!
quadrapus_leg_count = octopus_leg_count / 2
-- The pentapus has one more leg than a quadrapus!
pentapus_leg_count = quadrapus_leg_count + 1
-- The heptapus is one leg short of an octopus. Sad story.
heptapus_leg_count = octopus_leg_count - 1
-- The hexapus has twice as many legs as an octopus! Scary.
hexapus_leg_count = octopus_leg_count * 2
}}}
Whoa! That's a lot of stuff!
Okay first of all, see those ''lines with the two dashes {{{--}}} in front of them''? Those are ''comments''. Little remarks you can put so that you, and other people can get a clue as to what's going on in your code. They're completely ignored by Lua. As you can probably imagine, comments are sometimes handy when you want to keep parts of your code from running in your script. (Oh and there's another type of comment that can work multiple lines! {{{--[[ COMMENT GOES HERE ]]}}})
Now, we used a bunch of arithmetic there. We used {{{+}}} for addition, {{{-}}} for subtraction, {{{*}}} for multiplication, and {{{/}}} for division. There are other operations that can be done as well! {{{%}}} does modulo (remainder from division) and {{{^}}} does exponentation.
Now you can crunch out numbers to your heart's content!
!!String Operations
Now that we know how to do all sorts of crazy number manipulation, maybe we'd want to do stuff with text as well?
''This calls for strings.'' Strings are a way representing text in Lua.
Think of a big spool of phantasmal, thin rope-like fabric. We're in kindergarten again, so we're going to use our glue stick, our favorite construction paper and blue safety scissors to put our name on this string. We've just //strewn// together the letters, and clumped them on! Now we've got a pretty decoration to show off!
I just made mine, it says "ANDY" in red construction paper.
Now the Lua equivalent to that flashback to kindergarten is as follows:
{{{
name = "Andy"
}}}
The quotes are Lua's equivalent to construction paper and glue and physical spools of string. The text is now on display for Lua. And we put it in a variable called ''name''. We can use either ''single'' or ''double'' quotes.
Now what if we wanted to tell the rest of the world what our name is?
{{{
name = "Andy"
print(name)
}}}
This would tell everyone our name, Andy. But we didn't exactly introduce ourselves first. We just went straight to the names. Don't you remember anything about talking to people? You need to make that a complete sentence so you don't seem like some scary sociopath!
{{{
name = "Andy"
greeting = "Hello, resident. I am pleased to meet you. I kindly inform you that my name is " .. name .. "!"
}}}
Much better! Note the use of {{{.. }}} to put strings together with variables. It ''concatenates'' them. In //other words//, think of the strings being ''tied together'', and {{{..}}} is like tying a knot between the strings, //attaching// them to each other.
But what if we want to tell them how old we are, and we use a variable to figure out that number?
{{{
name = "Andy"
age = 2008 - 1988
greeting = "Hello, resident. I am pleased to meet you. I kindly inform you that my name is " .. name .. "!"
greeting = greeting .. " I am " .. tostring(age) .. " years old!"
}}}
This is where we use {{{tostring}}}. This turns a number (like {{{20}}}) into in a string (like {{{"20"}}}). Why the distinction between text and numbers? Who knows! Just remember that if you want to ''treat numbers as if they were text'', you need to //convert// them, hence {{{tostring}}}. Note the parentheses {{{()}}}around age there. They mean business. Don't forget them!
!!Table operations
Sometimes we have a bunch of similar data. We want to group it together, //somehow//. These are where ''tables'' come in handy!
The simplest kind of table is pretty much a list.
{{{
meals = {"Breakfast", "Lunch", "Dinner"}
}}}
We just made a list (or table!) of meals. {{{meals}}} is a table variable we made up. We can now retreive these things from the list, sort of like variables but with a small difference.
{{{
meals = {"Breakfast", "Lunch", "Dinner"}
message = "I had eggs for " .. meals[1] .. ", burritos for " .. meals[2] .. ", and steak for " .. meals[3] .. "!"
}}}
This puts {{{"I had eggs for Breakfast, burritos for Lunch, and steak for Dinner!"}}} into the variable {{{message}}}. Notice the square brackets {{{[]}}} with a number inside after refering to {{{meals}}}. This lets us get the first item, the second item, and the third item, and heck any item out of the table! We can even substitute that number in the {{{[]}}} for a number variable!
Maybe you want to be sneaky and switch up the meals? Try this!
{{{
meals = {"Breakfast", "Lunch", "Dinner"}
meals[0] = "Brunch"
meals[1] = "a Snack"
meals[2] = "my Birthday"
message = "I had eggs for " .. meals[1] .. ", burritos for " .. meals[2] .. ", and steak for " .. meals[3] .. "!"
}}}
This puts {{{"I had eggs for Brunch, burritos for a Snack, and steak for my Birthday!"}}} into the variable {{{message}}}.
Really, there's a lot of stuff to do with tables. I'll revisit this later and add all that information.
To do a simple program that displays "Hello world" on a black screen, here is the code:
{{{
require "vx"
function autoexec()
local text = "Hello World"
while true do
vx.screen:RectFill(0, 0, vx.screen.width, vx.screen.height, vx.RGB(0, 0, 0))
vx.default_font:Print(vx.screen.width / 2 - vx.default_font:TextWidth(text) / 2, vx.screen.height / 2, text)
vx.ShowPage()
end
end
}}}
/***
|''Name:''|LegacyStrikeThroughPlugin|
|''Description:''|Support for legacy (pre 2.1) strike through formatting|
|''Version:''|1.0.2|
|''Date:''|Jul 21, 2006|
|''Source:''|http://www.tiddlywiki.com/#LegacyStrikeThroughPlugin|
|''Author:''|MartinBudden (mjbudden (at) gmail (dot) com)|
|''License:''|[[BSD open source license]]|
|''CoreVersion:''|2.1.0|
***/
//{{{
// Ensure that the LegacyStrikeThrough Plugin is only installed once.
if(!version.extensions.LegacyStrikeThroughPlugin) {
version.extensions.LegacyStrikeThroughPlugin = {installed:true};
config.formatters.push(
{
name: "legacyStrikeByChar",
match: "==",
termRegExp: /(==)/mg,
element: "strike",
handler: config.formatterHelpers.createElementAndWikify
});
} //# end of "install only once"
//}}}
LuaVerge was the name decided upon for the verge engine when using Lua for scripting rather than VergeC. It basically mimics the VergeC API but with some very minor changes to make it more usable. All of the methods are contained within a package named {{{v3}}}. vx builds on LuaVerge, and abstracts the 'classic' and 'raw' way of doing Verge scripts.
[[vx contents|VXContents]]
[[variables|VXVariables]]
[[functions|VXFunctions]]
[[objects|VXObjects]]
<!--{{{-->
<div id='header'>
</div>
<div id='sidebar'>
<div id='titleLine'></div>
<div id='siteTitle' align="center" style='font-size:3.6em; color:#226633;' refresh='content' tiddler='SiteTitle'></div><div id='siteSubtitle' align="center" style='font-style: italic;' refresh='content' tiddler='SiteSubtitle'></div>
<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<div id='displayArea'>
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
/***
|<html><a name="Top"/></html>''Name:''|PartTiddlerPlugin|
|''Version:''|1.0.9 (2007-07-14)|
|''Source:''|http://tiddlywiki.abego-software.de/#PartTiddlerPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license]]|
|''CoreVersion:''|2.1.3|
|''Browser:''|Firefox 1.0.4+; InternetExplorer 6.0|
!Table of Content<html><a name="TOC"/></html>
* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Description',null, event)">Description, Syntax</a></html>
* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Applications',null, event)">Applications</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('LongTiddler',null, event)">Refering to Paragraphs of a Longer Tiddler</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Citation',null, event)">Citation Index</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('TableCells',null, event)">Creating "multi-line" Table Cells</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Tabs',null, event)">Creating Tabs</a></html>
** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Sliders',null, event)">Using Sliders</a></html>
* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Revisions',null, event)">Revision History</a></html>
* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Code',null, event)">Code</a></html>
!Description<html><a name="Description"/></html>
With the {{{<part aPartName> ... </part>}}} feature you can structure your tiddler text into separate (named) parts.
Each part can be referenced as a "normal" tiddler, using the "//tiddlerName//''/''//partName//" syntax (e.g. "About/Features"). E.g. you may create links to the parts (e.g. {{{[[Quotes/BAX95]]}}} or {{{[[Hobbies|AboutMe/Hobbies]]}}}), use it in {{{<<tiddler...>>}}} or {{{<<tabs...>>}}} macros etc.
''Syntax:''
|>|''<part'' //partName// [''hidden''] ''>'' //any tiddler content// ''</part>''|
|//partName//|The name of the part. You may reference a part tiddler with the combined tiddler name "//nameOfContainerTidder//''/''//partName//. <<br>>If you use a partName containing spaces you need to quote it (e.g. {{{"Major Overview"}}} or {{{[[Shortcut List]]}}}).|
|''hidden''|When defined the content of the part is not displayed in the container tiddler. But when the part is explicitly referenced (e.g. in a {{{<<tiddler...>>}}} macro or in a link) the part's content is displayed.|
|<html><i>any tiddler content</i></html>|<html>The content of the part.<br>A part can have any content that a "normal" tiddler may have, e.g. you may use all the formattings and macros defined.</html>|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
!Applications<html><a name="Applications"/></html>
!!Refering to Paragraphs of a Longer Tiddler<html><a name="LongTiddler"/></html>
Assume you have written a long description in a tiddler and now you want to refer to the content of a certain paragraph in that tiddler (e.g. some definition.) Just wrap the text with a ''part'' block, give it a nice name, create a "pretty link" (like {{{[[Discussion Groups|Introduction/DiscussionGroups]]}}}) and you are done.
Notice this complements the approach to first writing a lot of small tiddlers and combine these tiddlers to one larger tiddler in a second step (e.g. using the {{{<<tiddler...>>}}} macro). Using the ''part'' feature you can first write a "classic" (longer) text that can be read "from top to bottom" and later "reuse" parts of this text for some more "non-linear" reading.
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
!!Citation Index<html><a name="Citation"/></html>
Create a tiddler "Citations" that contains your "citations".
Wrap every citation with a part and a proper name.
''Example''
{{{
<part BAX98>Baxter, Ira D. et al: //Clone Detection Using Abstract Syntax Trees.//
in //Proc. ICSM//, 1998.</part>
<part BEL02>Bellon, Stefan: //Vergleich von Techniken zur Erkennung duplizierten Quellcodes.//
Thesis, Uni Stuttgart, 2002.</part>
<part DUC99>Ducasse, Stéfane et al: //A Language Independent Approach for Detecting Duplicated Code.//
in //Proc. ICSM//, 1999.</part>
}}}
You may now "cite" them just by using a pretty link like {{{[[Citations/BAX98]]}}} or even more pretty, like this {{{[[BAX98|Citations/BAX98]]}}}.
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
!!Creating "multi-line" Table Cells<html><a name="TableCells"/></html>
You may have noticed that it is hard to create table cells with "multi-line" content. E.g. if you want to create a bullet list inside a table cell you cannot just write the bullet list
{{{
* Item 1
* Item 2
* Item 3
}}}
into a table cell (i.e. between the | ... | bars) because every bullet item must start in a new line but all cells of a table row must be in one line.
Using the ''part'' feature this problem can be solved. Just create a hidden part that contains the cells content and use a {{{<<tiddler >>}}} macro to include its content in the table's cell.
''Example''
{{{
|!Subject|!Items|
|subject1|<<tiddler ./Cell1>>|
|subject2|<<tiddler ./Cell2>>|
<part Cell1 hidden>
* Item 1
* Item 2
* Item 3
</part>
...
}}}
Notice that inside the {{{<<tiddler ...>>}}} macro you may refer to the "current tiddler" using the ".".
BTW: The same approach can be used to create bullet lists with items that contain more than one line.
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
!!Creating Tabs<html><a name="Tabs"/></html>
The build-in {{{<<tabs ...>>}}} macro requires that you defined an additional tiddler for every tab it displays. When you want to have "nested" tabs you need to define a tiddler for the "main tab" and one for every tab it contains. I.e. the definition of a set of tabs that is visually displayed at one place is distributed across multiple tiddlers.
With the ''part'' feature you can put the complete definition in one tiddler, making it easier to keep an overview and maintain the tab sets.
''Example''
The standard tabs at the sidebar are defined by the following eight tiddlers:
* SideBarTabs
* TabAll
* TabMore
* TabMoreMissing
* TabMoreOrphans
* TabMoreShadowed
* TabTags
* TabTimeline
Instead of these eight tiddlers one could define the following SideBarTabs tiddler that uses the ''part'' feature:
{{{
<<tabs txtMainTab
Timeline Timeline SideBarTabs/Timeline
All 'All tiddlers' SideBarTabs/All
Tags 'All tags' SideBarTabs/Tags
More 'More lists' SideBarTabs/More>>
<part Timeline hidden><<timeline>></part>
<part All hidden><<list all>></part>
<part Tags hidden><<allTags>></part>
<part More hidden><<tabs txtMoreTab
Missing 'Missing tiddlers' SideBarTabs/Missing
Orphans 'Orphaned tiddlers' SideBarTabs/Orphans
Shadowed 'Shadowed tiddlers' SideBarTabs/Shadowed>></part>
<part Missing hidden><<list missing>></part>
<part Orphans hidden><<list orphans>></part>
<part Shadowed hidden><<list shadowed>></part>
}}}
Notice that you can easily "overwrite" individual parts in separate tiddlers that have the full name of the part.
E.g. if you don't like the classic timeline tab but only want to see the 100 most recent tiddlers you could create a tiddler "~SideBarTabs/Timeline" with the following content:
{{{
<<forEachTiddler
sortBy 'tiddler.modified' descending
write '(index < 100) ? "* [["+tiddler.title+"]]\n":""'>>
}}}
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
!!Using Sliders<html><a name="Sliders"/></html>
Very similar to the build-in {{{<<tabs ...>>}}} macro (see above) the {{{<<slider ...>>}}} macro requires that you defined an additional tiddler that holds the content "to be slid". You can avoid creating this extra tiddler by using the ''part'' feature
''Example''
In a tiddler "About" we may use the slider to show some details that are documented in the tiddler's "Details" part.
{{{
...
<<slider chkAboutDetails About/Details details "Click here to see more details">>
<part Details hidden>
To give you a better overview ...
</part>
...
}}}
Notice that putting the content of the slider into the slider's tiddler also has an extra benefit: When you decide you need to edit the content of the slider you can just doubleclick the content, the tiddler opens for editing and you can directly start editing the content (in the part section). In the "old" approach you would doubleclick the tiddler, see that the slider is using tiddler X, have to look for the tiddler X and can finally open it for editing. So using the ''part'' approach results in a much short workflow.
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
!Revision history<html><a name="Revisions"/></html>
* v1.0.9 (2007-07-14)
** Bugfix: Error when using the SideBarTabs example and switching between "More" and "Shadow". Thanks to cmari for reporting the issue.
* v1.0.8 (2007-06-16)
** Speeding up display of tiddlers containing multiple pard definitions. Thanks to Paco Rivière for reporting the issue.
** Support "./partName" syntax inside <<tabs ...>> macro
* v1.0.7 (2007-03-07)
** Bugfix: <<tiddler "./partName">> does not always render correctly after a refresh (e.g. like it happens when using the "Include" plugin). Thanks to Morris Gray for reporting the bug.
* v1.0.6 (2006-11-07)
** Bugfix: cannot edit tiddler when UploadPlugin by Bidix is installed. Thanks to José Luis González Castro for reporting the bug.
* v1.0.5 (2006-03-02)
** Bugfix: Example with multi-line table cells does not work in IE6. Thanks to Paulo Soares for reporting the bug.
* v1.0.4 (2006-02-28)
** Bugfix: Shadow tiddlers cannot be edited (in TW 2.0.6). Thanks to Torsten Vanek for reporting the bug.
* v1.0.3 (2006-02-26)
** Adapt code to newly introduced Tiddler.prototype.isReadOnly() function (in TW 2.0.6). Thanks to Paulo Soares for reporting the problem.
* v1.0.2 (2006-02-05)
** Also allow other macros than the "tiddler" macro use the "." in the part reference (to refer to "this" tiddler)
* v1.0.1 (2006-01-27)
** Added Table of Content for plugin documentation. Thanks to RichCarrillo for suggesting.
** Bugfix: newReminder plugin does not work when PartTiddler is installed. Thanks to PauloSoares for reporting.
* v1.0.0 (2006-01-25)
** initial version
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
!Code<html><a name="Code"/></html>
<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
***/
//{{{
//============================================================================
// PartTiddlerPlugin
// Ensure that the PartTiddler Plugin is only installed once.
//
if (!version.extensions.PartTiddlerPlugin) {
version.extensions.PartTiddlerPlugin = {
major: 1, minor: 0, revision: 9,
date: new Date(2007, 6, 14),
type: 'plugin',
source: "http://tiddlywiki.abego-software.de/#PartTiddlerPlugin"
};
if (!window.abego) window.abego = {};
if (version.major < 2) alertAndThrow("PartTiddlerPlugin requires TiddlyWiki 2.0 or newer.");
//============================================================================
// Common Helpers
// Looks for the next newline, starting at the index-th char of text.
//
// If there are only whitespaces between index and the newline
// the index behind the newline is returned,
// otherwise (or when no newline is found) index is returned.
//
var skipEmptyEndOfLine = function(text, index) {
var re = /(\n|[^\s])/g;
re.lastIndex = index;
var result = re.exec(text);
return (result && text.charAt(result.index) == '\n')
? result.index+1
: index;
}
//============================================================================
// Constants
var partEndOrStartTagRE = /(<\/part>)|(<part(?:\s+)((?:[^>])+)>)/mg;
var partEndTagREString = "<\\/part>";
var partEndTagString = "</part>";
//============================================================================
// Plugin Specific Helpers
// Parse the parameters inside a <part ...> tag and return the result.
//
// @return [may be null] {partName: ..., isHidden: ...}
//
var parseStartTagParams = function(paramText) {
var params = paramText.readMacroParams();
if (params.length == 0 || params[0].length == 0) return null;
var name = params[0];
var paramsIndex = 1;
var hidden = false;
if (paramsIndex < params.length) {
hidden = params[paramsIndex] == "hidden";
paramsIndex++;
}
return {
partName: name,
isHidden: hidden
};
}
// Returns the match to the next (end or start) part tag in the text,
// starting the search at startIndex.
//
// When no such tag is found null is returned, otherwise a "Match" is returned:
// [0]: full match
// [1]: matched "end" tag (or null when no end tag match)
// [2]: matched "start" tag (or null when no start tag match)
// [3]: content of start tag (or null if no start tag match)
//
var findNextPartEndOrStartTagMatch = function(text, startIndex) {
var re = new RegExp(partEndOrStartTagRE);
re.lastIndex = startIndex;
var match = re.exec(text);
return match;
}
//============================================================================
// Formatter
// Process the <part ...> ... </part> starting at (w.source, w.matchStart) for formatting.
//
// @return true if a complete part section (including the end tag) could be processed, false otherwise.
//
var handlePartSection = function(w) {
var tagMatch = findNextPartEndOrStartTagMatch(w.source, w.matchStart);
if (!tagMatch) return false;
if (tagMatch.index != w.matchStart || !tagMatch[2]) return false;
// Parse the start tag parameters
var arguments = parseStartTagParams(tagMatch[3]);
if (!arguments) return false;
// Continue processing
var startTagEndIndex = skipEmptyEndOfLine(w.source, tagMatch.index + tagMatch[0].length);
var endMatch = findNextPartEndOrStartTagMatch(w.source, startTagEndIndex);
if (endMatch && endMatch[1]) {
if (!arguments.isHidden) {
w.nextMatch = startTagEndIndex;
w.subWikify(w.output,partEndTagREString);
}
w.nextMatch = skipEmptyEndOfLine(w.source, endMatch.index + endMatch[0].length);
return true;
}
return false;
}
config.formatters.push( {
name: "part",
match: "<part\\s+[^>]+>",
handler: function(w) {
if (!handlePartSection(w)) {
w.outputText(w.output,w.matchStart,w.matchStart+w.matchLength);
}
}
} )
//============================================================================
// Extend "fetchTiddler" functionality to also recognize "part"s of tiddlers
// as tiddlers.
var currentParent = null; // used for the "." parent (e.g. in the "tiddler" macro)
// Return the match to the first <part ...> tag of the text that has the
// requrest partName.
//
// @return [may be null]
//
var findPartStartTagByName = function(text, partName) {
var i = 0;
while (true) {
var tagMatch = findNextPartEndOrStartTagMatch(text, i);
if (!tagMatch) return null;
if (tagMatch[2]) {
// Is start tag
// Check the name
var arguments = parseStartTagParams(tagMatch[3]);
if (arguments && arguments.partName == partName) {
return tagMatch;
}
}
i = tagMatch.index+tagMatch[0].length;
}
}
// Return the part "partName" of the given parentTiddler as a "readOnly" Tiddler
// object, using fullName as the Tiddler's title.
//
// All remaining properties of the new Tiddler (tags etc.) are inherited from
// the parentTiddler.
//
// @return [may be null]
//
var getPart = function(parentTiddler, partName, fullName) {
var text = parentTiddler.text;
var startTag = findPartStartTagByName(text, partName);
if (!startTag) return null;
var endIndexOfStartTag = skipEmptyEndOfLine(text, startTag.index+startTag[0].length);
var indexOfEndTag = text.indexOf(partEndTagString, endIndexOfStartTag);
if (indexOfEndTag >= 0) {
var partTiddlerText = text.substring(endIndexOfStartTag,indexOfEndTag);
var partTiddler = new Tiddler();
partTiddler.set(
fullName,
partTiddlerText,
parentTiddler.modifier,
parentTiddler.modified,
parentTiddler.tags,
parentTiddler.created);
partTiddler.abegoIsPartTiddler = true;
return partTiddler;
}
return null;
}
// Hijack the store.fetchTiddler to recognize the "part" addresses.
//
var hijackFetchTiddler = function() {
var oldFetchTiddler = store.fetchTiddler ;
store.fetchTiddler = function(title) {
var result = oldFetchTiddler.apply(this, arguments);
if (!result && title) {
var i = title.lastIndexOf('/');
if (i > 0) {
var parentName = title.substring(0, i);
var partName = title.substring(i+1);
var parent = (parentName == ".")
? store.resolveTiddler(currentParent)
: oldFetchTiddler.apply(this, [parentName]);
if (parent) {
return getPart(parent, partName, parent.title+"/"+partName);
}
}
}
return result;
};
};
// for debugging the plugin is not loaded through the systemConfig mechanism but via a script tag.
// At that point in the "store" is not yet defined. In that case hijackFetchTiddler through the restart function.
// Otherwise hijack now.
if (!store) {
var oldRestartFunc = restart;
window.restart = function() {
hijackFetchTiddler();
oldRestartFunc.apply(this,arguments);
};
} else
hijackFetchTiddler();
// The user must not edit a readOnly/partTiddler
//
config.commands.editTiddler.oldIsReadOnlyFunction = Tiddler.prototype.isReadOnly;
Tiddler.prototype.isReadOnly = function() {
// Tiddler.isReadOnly was introduced with TW 2.0.6.
// For older version we explicitly check the global readOnly flag
if (config.commands.editTiddler.oldIsReadOnlyFunction) {
if (config.commands.editTiddler.oldIsReadOnlyFunction.apply(this, arguments)) return true;
} else {
if (readOnly) return true;
}
return this.abegoIsPartTiddler;
}
config.commands.editTiddler.handler = function(event,src,title)
{
var t = store.getTiddler(title);
// Edit the tiddler if it either is not a tiddler (but a shadowTiddler)
// or the tiddler is not readOnly
if(!t || !t.abegoIsPartTiddler)
{
clearMessage();
story.displayTiddler(null,title,DEFAULT_EDIT_TEMPLATE);
story.focusTiddler(title,"text");
return false;
}
}
// To allow the "./partName" syntax in macros we need to hijack
// the invokeMacro to define the "currentParent" while it is running.
//
var oldInvokeMacro = window.invokeMacro;
function myInvokeMacro(place,macro,params,wikifier,tiddler) {
var oldCurrentParent = currentParent;
if (tiddler) currentParent = tiddler;
try {
oldInvokeMacro.apply(this, arguments);
} finally {
currentParent = oldCurrentParent;
}
}
window.invokeMacro = myInvokeMacro;
// To correctly support the "./partName" syntax while refreshing we need to hijack
// the config.refreshers.tiddlers to define the "currentParent" while it is running.
//
(function() {
var oldTiddlerRefresher= config.refreshers.tiddler;
config.refreshers.tiddler = function(e,changeList) {
var oldCurrentParent = currentParent;
try {
currentParent = e.getAttribute("tiddler");
return oldTiddlerRefresher.apply(this,arguments);
} finally {
currentParent = oldCurrentParent;
}
};
})();
// Support "./partName" syntax inside <<tabs ...>> macro
(function() {
var extendRelativeNames = function(e, title) {
var nodes = e.getElementsByTagName("a");
for(var i=0; i<nodes.length; i++) {
var node = nodes[i];
var s = node.getAttribute("content");
if (s && s.indexOf("./") == 0)
node.setAttribute("content",title+s.substr(1));
}
};
var oldHandler = config.macros.tabs.handler;
config.macros.tabs.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
var result = oldHandler.apply(this,arguments);
if (tiddler)
extendRelativeNames(place, tiddler.title);
return result;
};
})();
// Scroll the anchor anchorName in the viewer of the given tiddler visible.
// When no tiddler is defined use the tiddler of the target given event is used.
window.scrollAnchorVisible = function(anchorName, tiddler, evt) {
var tiddlerElem = null;
if (tiddler) {
tiddlerElem = document.getElementById(story.idPrefix + tiddler);
}
if (!tiddlerElem && evt) {
var target = resolveTarget(evt);
tiddlerElem = story.findContainingTiddler(target);
}
if (!tiddlerElem) return;
var children = tiddlerElem.getElementsByTagName("a");
for (var i = 0; i < children.length; i++) {
var child = children[i];
var name = child.getAttribute("name");
if (name == anchorName) {
var y = findPosY(child);
window.scrollTo(0,y);
return;
}
}
}
} // of "install only once"
//}}}
/***
<html><sub><a href="javascript:;" onclick="scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
!Licence and Copyright
Copyright (c) abego Software ~GmbH, 2006 ([[www.abego-software.de|http://www.abego-software.de]])
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
Neither the name of abego Software nor the names of its contributors may be
used to endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
<html><sub><a href="javascript:;" onclick="scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
***/
a verge extension paving the way for prettier code in LuaVerge!
/***
http://tiddlystyles.com/#theme:TiddlyPedia
***/
/*{{{*/
body
{
font-family: Georgia, Times, serif;
}
#titleLine{
display: block;
background: transparent url(wiki.png) no-repeat 18px -7px;
_background: transparent;
height: 120px;
_height: 135px;
width: 170px;
color: #000;
border: 1px;
padding: 0;
margin: 0;
}
* html #titleLine{
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='wiki.png',sizingMethod='scale');
}
#contentWrapper #siteTitle a{
display: inline;
font-weight: bold;
color: #000;
font-size: 13px;
}
#siteSubtitle{
padding: 0;
}
#siteTitle, #mainMenu{
position: static;
}
#contentWrapper #sidebar{
top: 0;
left: 0;
}
#displayArea {
margin: 0 0 0 15em;
}
#messageArea{
position: fixed;
top: 0;
right: 0;
font-size: 10px;
border: 1px solid #aaa;
background: #fff;
z-index: 25;
}
#messageArea a:link{
color: #002bb8;
text-decoration: none;
}
#messageArea a:hover{
text-decoration: underline;
}
.viewer{
background: #fff;
border: 1px solid #aaa;
padding: 1em;
margin: 0;
}
.body{
padding: 1px;
}
.title{
background: #fff;
border: 1px solid #aaa;
display: inline;
margin-left: .5em;
padding: 2px .5em;
border-bottom: 0;
font-weight: bold;
color: #000;
font-size: 1.2em;
}
.toolbar{
visibility: visible;
display: inline;
padding: 0;
font-family: sans-serif;
}
.toolbar a.button:link,.toolbar a.button:visited{
background: #fff;
border: 1px solid #aaa;
color:#002bb8;
font-size: 11px;
padding-bottom: 0;
margin-right: .25em;
}
/* Tiddly Pedia was Created by Clinton Checketts based on the Monobook skin of Wikipedia */
#contentWrapper .toolbar .button:hover{
border-bottom: 1px solid #fff;
background: #fff;
color:#002bb8;
}
.toolbar a.button:hover{
border-bottom: 1px solid #fff;
background: #fff;
color:#000;
}
#displayArea .viewer a,a.button:link,a.button:visited,
a.tiddlyLink:link,a.tiddlyLink:visited,
#sidebarOptions .sliderPanel a{
color:#002bb8;
background: transparent;
border: 0;
}
.viewer a:hover,a.button:hover,a.button:active,
a.tiddlyLink:hover,a.tiddlyLink:active,
.viewer a.button:hover,
#sidebarOptions .sliderPanel a:hover{
color:#002bb8;
background: transparent;
text-decoration: underline;
}
#mainMenu{
font-family: Georgia, Times, serif;
text-align: left;
font-size: x-small;
width: 100%;
margin: 0;
padding: 0;
}
#mainMenu h1{
font-size: 11px;
font-weight: normal;
padding: 0;
margin: 0;
background: transparent;
}
#mainMenu ul{
font-size: 11px;
border: 1px solid #aaa;
padding: .25em 0;
margin: 0;
list-style-type: square;
list-style-image: url(bullet.gif);
background: #fff;
width: 100%;
}
#mainMenu li{
margin: 0 0 0 2em;
padding: 0;
}
#contentWrapper #mainMenu a:link,#contentWrapper #mainMenu a:visited{
color:#002bb8;
padding: 0;
margin: 0;
background: transparent;
}
#mainMenu .externalLink {
text-decoration: none;
}
#mainMenu .externalLink:hover {
text-decoration: underline;
}
#sidebar{
padding: .5em;
c
}
#sidebarOptions{
border: 1px solid #aaa;
background: #fff;
margin-top: .5em;
width: 100%;
}
#sidebar .sliderPanel{
margin: 0;
}
#contentWrapper #sidebarOptions .button,#contentWrapper #sidebarOptions .button:hover{
color:#002bb8;
padding: .1em 0 .1em 2em;
background: transparent url(bullet.gif) 10px -2px no-repeat;
}
#sidebarOptions input{
width: 80%;
margin: 0 .5em;
}
#sidebarTabs{
background: #fff;
margin-top: .5em;
width: 100%;
}
#sidebarTabs .tabContents,#sidebarTabs .tabContents .tabContents{
border: 1px solid #aaa;
background: #fff;
}
#sidebarTabs .tabSelected,#sidebarTabs .tabcontents .tabSelected {
background: #fff;
border: 1px solid #aaa;
border-bottom: 0;
cursor: default;
padding-bottom: 3px;
color: #000;
}
#sidebarTabs .tabUnselected,#sidebarTabs .tabContents .tabUnselected{
background: #aaa;
padding-bottom: 0;
color: #000;
}
#contentWrapper #sidebarTabs .tiddlyLink,#contentWrapper #sidebarTabs .button,
#contentWrapper #sidebarTabs a.tiddlyLink:hover,#contentWrapper #sidebarTabs a.button:hover{
background: transparent;
color: #002bb8;
}
.footer{
margin: -1em 0 1em 0;
}
.footer .button:hover,.editorFooter .button:hover{
background: transparent;
color: #002bb8;
border-bottom: 1px solid #002bb8;
}
#popup{
background: #e9e9e9;
color: #000;
}
#popup hr{
border-color: #aaa;
background-color: #aaa;
}
#popup a{
color: #000;
}
#popup a:hover,#contentWrapper #sidebarTabs #popup a:hover{
background: #666;
color: #fff;
text-decoration: none;
}
#displayArea .tiddler a.tiddlyLinkNonExisting{
color: #ba0000;
}
#displayArea .tiddler a.externalLink{
text-decoration: none;
color:#002bb8;
padding-right: 1em;
background: transparent url(external.gif) 100% 50% no-repeat;
}
#displayArea .tiddler a.externalLink:hover{
text-decoration: underline;
}
.viewer pre{
background: #dee9ff;
border: 1px dashed #666;
}
.viewer h1, .viewer h2, .viewer h3, .viewer h4, .viewer h5, .viewer h6{
background: transparent;
border-bottom: .2em solid #aaa;
}
#sidebar .sliderPanel{
background: #e9e9e9;
}
#sidebar .sliderPanel input{width: auto;}
.tagged, .tagging, .listTitle{
float: none;
display: inline;
}
.tagged li, .tagging li,
.tagged ul, .tagging ul{
display: inline;
}
/*}}}*/
----
/***
CHANGES BY JOHN WENG. YOU HAVE BEEN WARNED.
***/
/*{{{*/
hr {height:4px;}
.viewer h1, .viewer h2, .viewer h3, .viewer h4, .viewer h5, .viewer h6{
background: transparent;
border-bottom: .02em solid #aaa;
color: #661144;
}
.viewer code { color: #660099;}
h1 {font-size:2.0em;}
h2 {font-size:1.75em;}
h3 {font-size:1.5em;}
h4 {font-size:1.25em;}
h5 {font-size:1.0em;}
blockquote { border: 0px; }
.textleft {text-align:left;}
.textright {text-align:right;}
.textcenter {text-align:center;}
/*}}}*/
!{{{vx.Button}}}
An internal object that represents a button's state.
!!Attributes:
{{{vx.Button.pressed -> boolean (read/write)}}}
*Whether or not this key is being held. Setting this to false will force the button to be let go.
!!Methods:
{{{vx.Button:Unpress()}}}
*Forces a button to be let go.
!{{{vx.Camera}}}
A singleton object that handles all the camera interaction
!!Attributes:
{{{vx.Camera.x -> number (read/write)}}}
{{{vx.Camera.y -> number (read/write)}}}
*The current position of the camera.
{{{vx.Camera.target -> number (read/write)}}}
*The camera targeting mode:
**{{{vx.Camera.TARGET_NOTHING}}} - full script control of the camera
**{{{vx.Camera.TARGET_PLAYER}}} - camera follows the player
**{{{vx.Camera.TARGET_ENTITY}}} - camera follows an entity
{{{vx.Camera.entity -> number (read/write)}}}
*The entity being followed, if the targeting mode is {{{vx.Camera.TARGET_ENTITY}}}.
!!Methods:
{{{vx.Camera:TargetNothing()}}}
*Makes the camera target nothing, allowing full script control of the camera.
{{{vx.Camera:TargetPlayer()}}}
*Makes the camera target the player and follow it around
{{{vx.Camera:TargetEntity(entity)}}}
*Makes the camera target an entity and follow it around
!{{{vx.Clock}}}
A singleton object that handles timing.
!!Attributes:
{{{vx.Clock.timer -> number (read/write)}}}
{{{vx.Clock.systemtime -> number (read)}}}
*Timing variables, both of which start at 0 when the program begins. They measure elapse in centiseconds of time. The {{{timer}}} variable can be written to unlike {{{systemtime}}}, which may be useful for timing some operations. Although, really, you can get away with just using timestamps. Ah well, the option's there.
!vx
vx, (preferrably pronounced 'vex' -- although 'vee echs' is okay too) a "[v]erge e[x]tension", attempts to wrap the raw LuaVerge library in a more modern, object-oriented approach, to cater to those of us (mainly me) who like lightly sprinkled object-orientation rather than procedural code in their Lua programs.
To use the vx namespace, simply make sure that the vx folder is contained as a subfolder in your game directory, and type:
{{{
require "vx"
}}}
This'll import the vx namespace, plus some other neat and very useful global functions. One of these useful things is overriding of Lua's builtin print function, so it'll direct the output to v3.log instead of the ignored stdout.
!!Downloading vx
To download vx, you will probably want a Subversion client (like [[TortoiseSVN|http://tortoisesvn.tigris.org/]] for Windows).
Then checkout this repository using the SVN client.
URL: http://www.verge-rpg.com/svn/vx/
Username: anonymous
Password: anonymous
!!Contents of the vx namepsace
* [[Variables contained by the vx namespace|VXVariables]]
* [[Functions contained the vx namespace|VXFunctions]]
* [[Objects and singletons contained the vx namespace|VXObjects]]
!!Examples using vx
* [[Hello world!|HelloWorld]]
!!Tutorials
* [[Get wet! Learn vx!|GetWetLearnVXTutorial]]
!{{{vx.Entity}}}
An object that represents a verge entity handle and performs various entity interactions. There are also a few static methods that are used to refer to all entities on-map.
!!Constructors:
{{{vx.Entity(handle_index)}}}
*For referencing map-defined entities by their index.
{{{vx.Entity(x, y, filename)}}}
*Opens a chr sprite and spawns an entity at (x, y).
!!Attributes:
{{{vx.Entity.x -> number (read/write)}}}
{{{vx.Entity.y -> number (read/write)}}}
*The map position of the entity in pixels
{{{vx.Entity.special_frame -> number (read/write)}}}
*A special animation frame to use, overrides normal frame drawing if this is non-zero.
{{{vx.Entity.hotspot_x -> number (read)}}}
{{{vx.Entity.hotspot_y -> number (read)}}}
{{{vx.Entity.hotspot_width -> number (read)}}}
{{{vx.Entity.hotspot_height -> number (read)}}}
*The rectangular area defined to be the entity's hotspot. Used for checking obstructions, and y-sorting rendering. The entity's (x, y) already have (hotspot_x, hotspot_y) added to them.
{{{vx.Entity.direction -> number (read/write)}}}
*The direction the entity is facing.
*''NOTE:'' Setting it to an invalid number can crash verge.
{{{
(up) 1
|
(left) 3 --+-- 4 (right)
|
2 (down)
}}}
{{{vx.Entity.speed -> number (read/write)}}}
*The speed of movement in pixels/sec. Defaults to 100.
{{{vx.Entity.visible -> boolean (read/write)}}}
*Whether or not this entity is drawn on the map.
{{{vx.Entity.is_obstruction -> boolean (read/write)}}}
*Whether or not this entity will be an obstruction to others.
{{{vx.Entity.obstructable -> boolean (read/write)}}}
*Whether or not this entity will obey obstructions, or just walk through things instead.
{{{vx.Entity.filename -> string (read/write)}}}
*The sprite filename for this entity. Changing this will load in the new filename specified.
{{{vx.Entity.lucent -> number (read/write)}}}
*The translucency of the entity.
{{{vx.Entity.frame_width -> number (read/write)}}}
{{{vx.Entity.frame_height -> number (read/write)}}}
*The actual dimensions of the sprite's each frame in pixels.
{{{vx.Entity.description -> string (read/write)}}}
*Information about this sprite, usually used in MapEd, to help you figure out which entity is which.
!!Static Methods
Just call these methods off the class itself rather than an object. Note the use of the {{{.}}} dot operator instead of {{{:}}} when calling. This is because static functions don't have a {{{self}}}.
{{{vx.Entity.Count() -> number}}}
*Returns the number of currently active entities.
{{{vx.Entity.PauseAll()}}}
*Stops entity movement codes from being processed until they are later unpaused.
{{{vx.Entity.UnpauseAll()}}}
*Resumes processing of entity movement.
!!Methods:
{{{vx.Entity:SetSprite(filename)}}}
*Changes the entity's sprite file.
{{{vx.Entity:Move(movescript)}}}
*Move the entity according to a movescript.
{{{vx.Entity:SetWanderDelay(delay)}}}
*Sets the pause between each step when wandering.
{{{vx.Entity:WanderRect(x, y, x2, y2)}}}
*Causes the entity to wander in a rectangular region.
{{{vx.Entity:WanderZone(x, y, x2, y2)}}}
*Causes the entity to wander within the confines of the zone it is currently standing in. All other types of zone are treated as obstructions.
{{{vx.Entity:HookRender(func)}}}
*Overrides the entity's rendering method to the specified global function.
{{{vx.Entity:Stalk(target)}}}
*Makes the entity follow another entity.
{{{vx.Entity:StopStalking()}}}
*Makes the entity stop following another entity around.
{{{vx.Entity:Stop()}}}
*Forces the entity to stop moving.
{{{vx.Entity:BecomePlayer()}}}
*Makes this entity become the "player" entity, which the user input moves around, and which the camera follows by default.
This table contains an enumeration of the various effects used by the @@font-family(monospace):font-size(1.6em):[[vx.Image:DefinedColorFilter(filter)|VXImageObject]]@@ method. These are the available entries:
{{{vx.FilterEffect.None}}} - nothing
{{{vx.FilterEffect.Greyscale}}} - greyscale
{{{vx.FilterEffect.Invert}}} - inverted colors
{{{vx.FilterEffect.GreyscaleInvert}}} - greyscale and invert
{{{vx.FilterEffect.Red}}} - "redscale"
{{{vx.FilterEffect.Green}}} - "greenscale"
{{{vx.FilterEffect.Blue}}} - "bluescale"
{{{vx.FilterEffect.Custom}}} - a custom filter
To define what {{{vx.FilterEffect.Custom}}} will do, use @@font-family(monospace):font-size(1.6em):[[vx.SetCustomColorFilter(color1, color2)|VXFunctions]]@@
!{{{vx.Font}}}
An object that represents a verge font handle and performs various printing operations.
!!Constructors:
{{{vx.Font(handle_index)}}}
*Wraps around a raw verge handle. It is doubtful you'll need to use this, as the only real objects that need to be raw handles to begin with is font 0.
{{{vx.Font(filename, width, height)}}}
*Open an font image from disk.
''IMPORTANT:'' Remember to explicitly call the {{{Free()}}} method when you're
done with a font or else it'll leak memory.
!!Attributes:
{{{vx.Font.height -> number (read)}}}
*The height of the font in pixels
!!Methods:
{{{vx.Font:Free()}}}
*Destroys the font handle. Any further font operations on this object will probably not end so pretty.
{{{vx.Font:EnableVariableWidth()}}}
*Enables variable width on the font, allowing each character in the font to be of a different width.
{{{vx.Font:SetCharacterWidth(character, width)}}}
*Forces a specific character to be the given width in pixels wide.
{{{vx.Font:TextWidth(text) -> number}}}
*Gets the width of the given text string in pixels
{{{vx.Font:Print(x, y, text, [dest])}}}
*Draws the given text to the specified spot on a destination image. If destination is not given, it assumes you want the screen.
{{{vx.Font:PrintRight(x, y, text, [dest])}}}
*Prints the text with right justification at (x, y)
{{{vx.Font:PrintCenter(x, y, text, [dest])}}}
*Prints the text centered at (x, y)
!Functions contained the vx namespace
{{{vx.Render()}}}
*Draws the map, if any, to the screen.
*''See also:'' @@font-family(monospace):font-size(1.6em):[[vx.map:Render|VXMapSingleton]]@@
{{{vx.ShowPage()}}}
*Flips the buffers and transfers any video changes to the screen. Also refreshes the input and processes a bunch of engine hooks.
{{{vx.UpdateControls()}}}
*Refreshes the input devices.
{{{vx.CallFunction(func)}}}
*Attempts to resolve and call a global function by its name. You might want to just use Lua function pointers where you can, since this primarily used for looking up map events.
{{{vx.Log(...)}}}
*Prints the passed list of arguments as a string with tabs between each message. If the object attempting to be printed does not have a {{{tostring()}}} representation, it will inevitably do bad stuff. So be careful if you're using the class system which [[LuaBind|http://www.rasterbar.com/products/luabind.html]](the library Verge uses to bind to lua) provides, because you need a {{{__tostring()}}} object method. If you want messages to not be tabulated, use the {{{..}}} string concatination operator instead of a comma!
{{{vx.Exit(...)}}}
*Exits verge with the passed list of arguments as a quit message, each separated by tabs. Same deal as vx.Log as far as possible problems. If you want messages to not be tabulated, use the {{{..}}} string concatination operator instead of a comma!
{{{vx.RGB(red, green, blue) -> number}}}
{{{vx.MakeColor(red, green, blue) -> number}}}
*Returns an RGB color index with the specified RGB values.
{{{vx.MixColor(color1, color2, ratio)}}}
*Returns an RGB color that is a mix of the two passed colors where ratio (values 0-255) determines the strength of each color. When ratio is 0, it will return color1, at 255 will return color 2, while a ratio of 128 will return a perfect blend of the two.
{{{vx.GetR(color) -> number}}}
*Returns the red channel of an RGB color.
{{{vx.GetG(color) -> number}}}
*Returns the green channel of an RGB color.
{{{vx.GetB(color) -> number}}}
*Returns the blue channel of an RGB color.
{{{vx.HSV(hue, saturation, value) -> number}}}
*Returns an RGB color index with the specified HSV values.
{{{vx.GetH(color) -> number}}}
*Returns the hue (a 0-359 position on the color spectrum) of an RGB color.
{{{vx.GetS(color) -> number}}}
*Returns the saturation (a 0-255 measure of 'coloredness') of an RGB color.
{{{vx.GetV(color) -> number}}}
*Returns the value (brightness) of an RGB color.
{{{vx.SetLucent(lucent)}}}
*Changes the percentage of translucency of drawing operations, taking in the range 0-100%. 0 is fully opaque, 100 is completely invisible.
{{{vx.GetLucent() -> number}}}
* Returns the current (most recently set) translucency, ranging from 0-100%. 0 is fully opaque, 100 is completely invisible.
{{{vx.SetOpacity(opacity)}}}
*Changes the percentage of opacity of drawing operations, taking in the range 0-100%. 100 is fully opaque, 0 is completely invisible. Setting either the opacity or translucency will set both to appropriate values; the opacity option is provided purely for semantic convenience.
{{{vx.GetOpacity()}}}
*Returns the current (most recently set) opacity, ranging from 0-100%. 100 is fully opaque, 0 is completely invisible. Setting either the opacity or translucency will set both to appropriate values; the opacity option is provided purely for semantic convenience.
{{{vx.Random(low, high) -> number}}}
*Returns a random number between low and high, inclusive.
{{{vx.SetAppName(title)}}}
*Changes the title of the application to the specified title string.
{{{vx.SetResolution(xres, yres)}}}
*Changes the title of the application to the specified title string.
{{{vx.SetCustomColorFilter(color1, color2)}}}
*Creates a custom color filter with colors in between color1 and color2. This filter can then be used by calling the @@font-family(monospace):font-size(1.6em):[[vx.Image:DefinedColorFilter(vx.FilterEffect.Custom)|VXImageObject]]@@ method. Alternatively just use the @@font-family(monospace):font-size(1.6em):[[vx.Image:ColorFilter(color1, color2)|VXImageObject]]@@ method.
!{{{vx.Image}}}
An object that represents a verge image handle and performs various raster operations.
!!Constructors
{{{vx.Image(handle_index)}}}
* Wraps around a raw verge handle. It is doubtful you'll need to use this, as the only real objects that need to be raw handles to begin with are the screen and the map's tileset.
{{{vx.Image(filename)}}}
*Open an image format from disk.
{{{vx.Image(width, height)}}}
* Creates a new image object of the specified dimensions.
{{{vx.Image(image)}}}
*Copy constructor which duplicates the raw image being represented by the specified image object.
''IMPORTANT'': Remember to explicitly call the {{{Free()}}} method when you're done with an image or else it'll leak memory.
!!Attributes
{{{vx.Image.width -> number (read)}}}
{{{vx.Image.height -> number (read)}}}
*Returns the dimensions of the image in pixels.
!!Methods
{{{vx.Image:Free()}}}
*Destroys the image handle. Any further image operations on this object will probably not end so pretty.
{{{vx.Image:Rect(x, y, x2, y2, color)}}}
* Draws a rectangular outline from (x, y) to (x2, y2) in the given color
{{{vx.Image:RectFill(x, y, x2, y2, color)}}}
* Draws a filled rectangular region from (x, y) to (x2, y2) in the given color
{{{vx.Image:Fill(color)}}}
* Completely fills the image with the specified color.
{{{vx.Image:RectHGrad(x, y, x2, y2, color1, color2)}}}
* Draws a filled rectangular region from (x, y) to (x2, y2) filled by a horizontal gradient from color1 to color2.
{{{vx.Image:RectVGrad(x, y, x2, y2, color1, color2)}}}
*Draws a filled rectangular region from (x, y) to (x2, y2) filled by a vertical gradient from color1 to color2.
{{{vx.Image:RectRGrad(x, y, x2, y2, color1, color2)}}}
*Draws a filled rectangular region from (x, y) to (x2, y2) filled by a radial gradient from color1 to color2.
{{{vx.Image:Rect4Grad(x, y, x2, y2, color1, color2, color3, color4)}}}
*Draws a filled rectangular region from (x, y) to (x2, y2) filled by a 4-point gradient with a color at each of the four corners.
{{{vx.Image:Circle(x, y, xrad, yrad, color)}}}
*Draws a circlular outline centered at (x, y) with radiuses (xrad, yrad) in the given color
{{{vx.Image:CircleFill(x, y, xrad, yrad, color)}}}
*Draws a filled circlular region centered at (x, y) with radiuses (xrad, yrad) in the given color
{{{vx.Image:Triangle(x, y, x2, y2, x3, y3, color)}}}
*Draws a filled triangle region defined by the points (x, y), (x2, y2), (x3, y3) in the given color. This is a messy triangle fill and not very accurate.
{{{vx.Image:Line(x, y, x2, y2, color)}}}
*Draws a line from from (x, y) to (x2, y2) in the given color.
{{{vx.Image:GetPixel(x, y) -> number}}}
*Returns the RGB color index of the pixel at (x, y) on the image.
{{{vx.Image:SetPixel(x, y, color)}}}
*Changes the pixel at (x, y) to the color specified.
{{{vx.Image:Mosaic(xgran, ygran)}}}
*Applies an Final Fantasy-style "mosaic" effect on the image according to the horizontal and vertical granularity
{{{vx.Image:DefinedColorFilter(filter)}}}
*Applies a color filter to the image.
* See the @@font-family(monospace):font-size(1.6em):[[vx.FilterEffect|VXFilterEffectTable]]@@ table documentation to figure out which filter values are permissible.
{{{vx.Image:Invert()}}}
*Inverts the colors of the image.
{{{vx.Image:Greyscale()}}}
*Converts the image to greyscale (black and white).
{{{vx.Image:GreyscaleInvert()}}}
*Converts the image to greyscale and inverts it.
{{{vx.Image:Red()}}}
*Applies a strong red tint to the image.
{{{vx.Image:Green()}}}
*Applies a strong green tint to the image.
{{{vx.Image:Blue()}}}
*Applies a strong blue tint to the image.
{{{vx.Image:ColorFilter(color1, color2)}}}
*Applies a custom color filter using the two supplied colors. This will not interfere with an independently defined custom color filter.
{{{vx.Image:HueReplace(oldhue, tolerance, newhue)}}}
*Finds a range of hues within an image and replaces them with another. Useful for color swapping in images with lots of colors.
{{{vx.Image:ColorReplace(oldcolor, newcolor)}}}
*Finds a specific color in an image and replaces it with another.
{{{vx.Image:BlitTile(x, y, tile)}}}
*Draws the specified tile represented by the current map's tile index at (x, y) onto the image.
{{{vx.Image:Blit(x, y, [dest])}}}
*Draws this image onto a destination image at the given (x, y), skipping over death magenta (pixels with RGB(255, 0, 255)). If dest is not supplied, the screen handle is assumed.
{{{vx.Image:FullBlit(x, y, [dest])}}}
* Draws this image onto a destination image at the given (x, y). This does not skip any pixels. If dest is not supplied, the screen handle is assumed.
{{{vx.Image:AdditiveBlit(x, y, [dest])}}}
* Like Blit, except it additively blends the pixels. This means that the RGB between this image and the overlapped dest region are added together, causing everything to become brighter. This is useful for lighting/glow effects. Death magenta is not added.
{{{vx.Image:SubtractiveBlit(x, y, [dest])}}}
* Like Blit, except it subtractively blends the pixels. This means that the RGB of the overlapped dest region are subtracted by this image's RGB values, causing everything to become darker. This is useful for shadow effects. Death magenta is not subtracted.
{{{vx.Image:GrabRegion(x, y, x2, y2, dest_x, dest_y, [dest])}}}
* Like Blit, but it only draws a rectangular subregion of the image to the destination.
{{{vx.Image:FullGrabRegion(x,y,x2,y2,dest_x,dest_y, [dest])}}}
* Like ~FullBlit, but it only draws a rectangular subregion of the image to the destination. This does not skip any pixels. If dest is not supplied, the screen handle is assumed.
{{{vx.Image:AlphaBlit(x, y, alpha_map, [dest])}}}
* Like Blit, but it treats a greyscale "alpha map" image as a channel that denotes translucency on the image. Death magenta WILL be drawn, because it assumes your alpha map takes care of all transparent regions.
{{{vx.Image:ScaleBlit(x, y, dw, dh, [dest])}}}
* Like Blit, but it takes width and height dimensions which the image will be appropriately shrunk or stretched to when drawn.
{{{vx.Image:RotateBlit(x, y, angle, [dest])}}}
* Like Blit, but it takes an angle to rotate the image by.
* Note: the image will be placed and rotated around the center of the image, not the upper-left corner as with most blitting operations.
{{{vx.Image:RotScale(x, y, angle, scale, [dest])}}}
{{{vx.Image:RotateScaleBlit(x, y, angle, scale, [dest])}}}
* Like Blit, but it takes an angle and a factor to scale the image by. A scale of 1 is normal. A scale of 2 is twice as big. A scale of 0.5 is half as big.
* Note: the image will be placed and rotated around the center of the image, not the upper-left corner as with most blitting operations.
* ''IMPORTANT'': As you may have noticed, unlike VC, the scale takes a decimal, not a number out of 1000.
{{{vx.Image:Silhouette(x, y, color, [dest])}}}
*Like Blit, but it draws all non-transparent in a solid color.
{{{vx.Image:WrapBlit(x, y, color, [dest])}}}
*Tiles the image onto the destination, respecting clip regions on the destination, with (x, y) as offset coordinates. Useful for creating scrolling backgrounds.
{{{vx.Image:SetClip(x, y, x2, y2)}}}
*Changes the clipping region of the image, effectively "cutting off" any drawing operations outside of the clipped rectangle specified.
{{{vx.Image:ImageShell(x, y, x2, y2)}}}
*Creates an image that represents a subregion in this image. Any changes done to either this image or the shell image will affect both.
{{{vx.Image:CopyImageToClipboard()}}}
*Copies this image into the clipboard, making it possible to paste outside this program. Useful for screen captures where you don't want the window to be included in the display.
!{{{vx.Map}}}
A singleton object that handles all map interaction.
!!Attributes
{{{vx.Map.width -> number (read)}}}
{{{vx.Map.height -> number (read)}}}
*The dimensions of the map, in tiles.
{{{vx.Map.start_x -> number (read)}}}
{{{vx.Map.start_y -> number (read)}}}
*The default tile position to spawn the player, specified by the map.
{{{vx.Map.title -> string (read)}}}
*The title of the active map.
{{{vx.Map.filename -> string (read/write)}}}
*The filename of the map currently being used. Changing the filename does the equivalent of the {{{Switch(filename)}}} method
{{{vx.Map.music_filename -> string (read)}}}
*The filename of the music to be played when this map is used.
{{{vx.Map.layer[layer_index] -> vx.Map.Layer}}}
*Resolves a layer by the specified index.
*This layer object has the following attributes:
**{{{layer.layer_index -> number (read)}}}
***The index in the array of the layer being looked up.
**{{{layer.lucent -> number (read)}}}
***Translucency percentage of the layer.
**{{{layer.parallax_x -> number (read/write)}}}
**{{{layer.parallax_y -> number (read/write)}}}
***The layer's parallax scrolling effects. I *think* it's specified as a 16.16 fixed point number! Lua doesn't have bitshift though, so you have to multiply/divide by 65536. I *could* possibly make it so the interaction is a decimal where the number 1 is a "normal" static layer.
**{{{layer.width -> number (read)}}}
**{{{layer.height -> number (read)}}}
***The dimensions of the layer in tiles.
{{{vx.Map.zone[zone_index] -> vx.Map.Zone}}}
*Resolves a zone by the specified index.
*This zone object has the following attributes:
**{{{zone.zone_index -> number (read)}}}
***The index in the array of the zone being looked up.
**{{{zone.name -> string (read)}}}
***Returns the name of the zone, as specified by its on-map description.
**{{{zone.event -> string (read)}}}
***The name of the global/map function to call if this zone were activated. Useful in custom engine loops where you have to handle zone interaction manually.
{{{vx.Map.tileset -> vx.Image (read)}}}
*Returns an image of the current map's tileset. Any modifications to this image affect the on-map tileset, allowing for some neat effects!
!!Methods
{{{vx.Map:Switch(filename)}}}
*Attempts to switch maps.
*''IMPORTANT:'' Unlike with VergeC, LuaVerge scripts do not automatically halt when the map is switched, so it is up to you to break out of any loops and functions before it will actually process the map switch request.
{{{vx.Map:Render([x, [y, [dest]]])}}}
*Draws the map at the specified coordinates, to the specified image destination. If x or y are not specified, it will use the camera's current position. If dest is not specified, it will draw the render to the screen.
{{{vx.Map:GetTile(x, y, layer) -> number}}}
*Returns the tile index at the specified (x, y) location on the given layer of the map.
{{{vx.Map:SetTile(x, y, layer, tile)}}}
*Changes the tile index at the specified (x, y) location on the given layer of the map to the given tile.
{{{vx.Map:GetObs(x, y) -> number}}}
*Gets the tile index of the obstruction tile at the specified (x, y) tile location. A tile of 0 is typically empty obstructions, but it entirely depends on the map being used. To make sure you're handling obstructions properly, you may want to use {{{GetObsPixel(x, y)}}} instead
{{{vx.Map:GetObsPixel(x, y) -> boolean}}}
*Gets whether or not the specified on-map (x, y) pixel location contains an obstruction. Note that this returns a boolean, whereas {{{GetObs(x, y)}}} returns a tile number.
{{{vx.Map:SetObs(x, y, tile)}}}
*Changes the obstruction tile at the specified (x, y) location on the map to the given tile.
{{{vx.Map:GetZone(x, y) -> number}}}
*Gets the zone index at the specified (x, y) tile location. A zone of 0 means the default map zone, for which no event SHOULD be associated. It is up to you to figure out what the numbering means. The {{{zone[]}}} attributes of the map may be useful for looking up name or scripts associated with a zone.
{{{vx.Map:SetZone(x, y, zone)}}}
*Changes the zone at the specified (x, y) location on the map to the given zone index.
!{{{vx.Music}}}
*A singleton object that handles the "simple" music interaction. Any music set to load when a map starts by a .map file must be managed through here.
!!Methods:
{{{vx.Music:Play(filename)}}}
*Changes the active music to the specified file.
{{{vx.Music:Stop()}}}
*Stops the actively playing music
{{{vx.Music:SetVolume(volume)}}}
*Changes the music volume to the value specified.
!Objects and singletons contained the vx namespace
@@font-family(monospace):font-size(1.6em):[[vx.Image|VXImageObject]]@@
*An object that represents a verge image handle and performs various raster operations.
@@font-family(monospace):font-size(1.6em):[[vx.Font|VXFontObject]]@@
*An object that represents a verge font handle and performs various printing operations.
@@font-family(monospace):font-size(1.6em):[[vx.Sound|VXSoundObject]]@@
*An object that represents a verge sound handle that can be played.
@@font-family(monospace):font-size(1.6em):[[vx.Song|VXSongObject]]@@
*An object that represents a verge song handle that can be played.
@@font-family(monospace):font-size(1.6em):[[vx.Socket|VXSocketObject]]@@
*An object that represents a verge socket handle and performs various network operations.
@@font-family(monospace):font-size(1.6em):[[vx.Entity|VXEntityObject]]@@
*An object that represents a verge entity handle and performs various entity interactions. There are also a few static methods that are used to refer to all entities on-map.
@@font-family(monospace):font-size(1.6em):[[vx.FilterEffect|VXFilterEffectTable]]@@
*This table contains an enumeration of the various effects used by the @@font-family(monospace):font-size(1.6em):[[vx.Image:DefinedColorFilter(filter)|VXImageObject]]@@ method.
@@font-family(monospace):font-size(1.6em):[[vx.Map|VXMapSingleton]]@@
*A singleton object that handles all map interaction.
@@font-family(monospace):font-size(1.6em):[[vx.Camera|VXCameraSingleton]]@@
*A singleton object that handles all the camera interaction
@@font-family(monospace):font-size(1.6em):[[vx.Button|VXButtonObject]]@@
*An internal object that represents a button's state.
@@font-family(monospace):font-size(1.6em):[[vx.Clock|VXClockSingleton]]@@
*A singleton object that handles timing operations.
@@font-family(monospace):font-size(1.6em):[[vx.Music|VXMusicSingleton]]@@
*A singleton object that handles the "simple" music interaction
!{{{vx.Socket}}}
An object that represents a verge socket handle and performs various network operations.
!!Constructors:
{{{vx.Socket()}}}
*This creates a Socket object. It does not automatically perform any operations. If you construct a Socket without parameters, you must either {{{Connect()}}} or {{{GetConnection()}}} successfully before can do anything else with it. This is mostly intended for use with {{{GetConnection()}}} to make a server with Verge.
{{{vx.Socket(address, [port])}}}
*Wraps around a raw socket handle. On construction, creates and connects to a new socket at the specified address on the supplied port. If no port is specified, it assumes Verge's default port (45150).
''IMPORTANT:'' Remember to explicitly call the {{{Free()}}} method when you're
done with a socket or else it'll leak memory / sockets!
!!Methods:
{{{vx.Socket:Free()}}}
{{{vx.Socket:Close()}}}
*Destroys the socket handle. Any further socket operation on this object will probably not end so pretty.
{{{vx.Socket:Connect(address, port)}}}
*Connects the socket to the supplied address and port. It is very unlikely you will ever nead this as it is performed for you on Socket construction.
{{{vx.Socket:Listen([port])}}}
{{{vx.Socket:GetConnection([port])}}}
*Checks for new connections on the specified port. If no port is supplied, it will use Verge's default (45150). If a new connection is found, the Socket will then assume that connection; if you are accepting multiple connections, you will need to create a new Socket for every connection.
{{{vx.Socket:Connected() -> boolean}}}
*Returns whether or the socket is currently connected. Much like its VergeC equivalent, it shouldn't be considered particularly reliable and implementing an alternative method, such as a timeout, is recommended.
{{{vx.Socket:HasData() -> boolean}}}
*Returns whether or not there is any data in the socket's queue waiting to be read/processed.
{{{vx.Socket:ByteCount() -> number}}}
*Returns the number of bytes/characters currently in the socket's queue waiting to be read/processed. This is primarily intended for use with getting and sending raw data. It should be noted, though, that if a verge int or string packet is in the queue, the header will be included in the byte count. However, if you are using a non-raw transmissions, {{{HasData()}}} should be sufficient (and probably faster) than {{{ByteCount()}}} anyway.
{{{vx.Socket:GetInt() -> number}}}
*Returns an integer number value acquired from the socket's data queue. If it receives a non-integer value, bad things will happen. Make certain that a socket only attempts to retrieve data of a type that is actualy being sent to it.
{{{vx.Socket:SendInt(integer)}}}
*Sends an integer number value through the socket. If the other end is not expecting an integer, something bad may happen to it, but the sender will probably be unharmed.
{{{vx.Socket:GetString() -> string}}}
*Returns a string value acquired from the socket's data queue. If it receives a non-string value, bad things will happen. Make certain that a socket only attempts to retrieve data of a type that is actually being sent to it.
{{{vx.Socket:SendString(value)}}}
*Sends a string value through the socket. If the other end is not expecting a string, something bad may happen to it, but the sender will probably be unharmed.
{{{vx.Socket:GetRaw(length) -> string}}}
*Returns a string value acquired from the socket's data queue. This string does not contain any of the Verge-string header information and is best suited for communicating with a non-Verge program within Verge itself. Exercise extreme caution when using this as there is even less hand-holding than with the other socket operations.
{{{vx.Socket:SendRaw()}}}
*Sends a raw (non-Verge) string through the socket. This string does not contain any of the Verge-string header information and is best suited for communicating with a non-Verge program within Verge itself. Exercise extreme caution when using this as there is even less hand-holding than with the other socket operations.
!{{{vx.Song}}}
An object that represents a verge song handle that can be played.
!!Constructors
{{{vx.Song(filename)}}}
*Tries to load a song from disk.
''IMPORTANT:'' Remember to explicitly call the {{{Free()}}} method when you're
done with a song or else it'll leak memory.
!!Attributes
{{{vx.Song.volume -> number (read/write)}}}
*The volume of this song in the range 0-100%.
{{{vx.Song.position -> number (read/write)}}}
*The position in this song, which depends on the file format being played as far as what this number represents.
!!Methods
{{{vx.Song:Free()}}}
*Destroys the song handle. Any further sound operations on this object will probably not end so pretty.
{{{vx.Song:Play([volume])}}}
*Plays the song.
{{{vx.Song:Stop()}}}
*Stops the song.
{{{vx.Song:Pause()}}}
*Pauses the song, keeping track of position for later resume
{{{vx.Song:Resume()}}}
*Plays the song, resuming from the position it was paused from. It'll probably not resume if the song was fully stopped.
!{{{vx.Sound}}}
An object that represents a verge sound handle that can be played.
!!Constructors:
{{{vx.Sound(filename)}}}
*Tries to load a sound from a file on disk.
''IMPORTANT:'' Remember to explicitly call the {{{Free()}}} method when you're
done with a sound or else it'll leak memory.
!!Methods:
{{{vx.Sound:Free()}}}
*Destroys the sound handle. Any further sound operations on this object will probably not end so pretty.
{{{vx.Sound:Play([volume]) -> vx.SoundChannel}}}
*Plays the sound, and returns a sound channel object.
*Each sound channel has the following methods:
**{{{channel:Stop()}}}
***Stops the sound immediately.
**{{{channel:IsPlaying() -> boolean}}}
***Returns whether or not this channel is still active.
!Variables contained by the vx namespace
{{{vx.map -> }}} @@font-family(monospace):font-size(1.6em):[[vx.Map|VXMapSingleton]]@@
*The map singleton
{{{vx.camera -> }}} @@font-family(monospace):font-size(1.6em):[[vx.Camera|VXCameraSingleton]]@@
*The camera singleton
{{{vx.clock -> }}} @@font-family(monospace):font-size(1.6em):[[vx.Clock|VXClockSingleton]]@@
*The clock singleton
{{{vx.music -> }}} @@font-family(monospace):font-size(1.6em):[[vx.Music|VXMusicSingleton]]@@
*The camera singleton
{{{vx.default_font -> }}} @@font-family(monospace):font-size(1.6em):[[vx.Font|VXFontObject]]@@
*A font object wrapping the builtin default verge font handle.
{{{vx.screen -> }}} @@font-family(monospace):font-size(1.6em):[[vx.Image|VXImageObject]]@@
*An image object wrapping the screen handle.
{{{vx.mouse -> vx.MouseInput}}}
*The object representing the mouse.
*It has the following attributes:
**{{{vx.mouse.x -> number}}}
**{{{vx.mouse.y -> number}}}
***The location of the mouse
**{{{vx.mouse.wheel -> number}}}
***A number refering to the mouse wheel location
**{{{vx.mouse.left -> }}} @@font-family(monospace):font-size(1.6em):[[vx.Button|VXButtonObject]]@@
**{{{vx.mouse.middle -> }}} @@font-family(monospace):font-size(1.6em):[[vx.Button|VXButtonObject]]@@
**{{{vx.mouse.right -> }}} @@font-family(monospace):font-size(1.6em):[[vx.Button|VXButtonObject]]@@
***The left, middle and right buttons of the mouse.
{{{vx.key["KeyName"] -> }}} @@font-family(monospace):font-size(1.6em):[[vx.Button|VXButtonObject]]@@
{{{vx.key.KeyName -> }}} @@font-family(monospace):font-size(1.6em):[[vx.Button|VXButtonObject]]@@
* An array of all the keyboard keys. The numeric keyboard keys need to be referenced with the array {{{[]}}} table notation, but everything else can be referenced using the dot {{{.}}} table notation.
* Here are the valid scancode names: {{{Escape
1
2
3
4
5
6
7
8
9
0
Minus
Equals
Backspace
Tab
Q
W
E
R
T
Y
U
I
O
P
LeftAangle
RightAngle
Enter
Ctrl
A
S
D
F
G
H
J
K
L
Semicolon
Apostrophe
Grave
LeftShift
Backslash
Z
X
C
V
B
N
M
Comma
Dot
Slash
RightShift
Star
Alt
Space
CapsLock
F1
F2
F3
F4
F5
F6
F7
F8
F9
F10
NumLock
ScrollLock
NumpadHome
Up
NumpadPageUp
NumpadMinus
Left
Numpad5
Right
NumpadPlus
NumpadEnd
Down
NumpadPageDown
NumpadInsert
NumpadDelete
F11
F12
Insert
Delete
Home
End
PageUp
PageDown}}}
VergeC is the default scripting language for Verge. It has been around since the beginning of scripting with the Verge engine, and shares a syntax very close to C. It sadly has very limited ways of managing dynamic memory and structures, requiring integer handles and global variables everywhere.
Not everyone liked the limitations of this language, and so [[ika|http://ika.sf.net/]] was born, a Python-based object oriented game making engine. Then much later LuaVerge was born, which took the raw VergeC and shoved it into Lua. Then vx was born to be an enhancement to LuaVerge, slightly inspired by ika and mostly driven by a desire to have a flexible and simple-to-use object-oriented API.
<!--{{{-->
<div class='title' macro='view title'></div>
<div class='toolbar' macro='toolbar -closeTiddler closeOthers +editTiddler permalink references jump'></div>
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->