Which language to use?

You have the choice between C-Script, lite-C, C, or C++. Other languages like Basic, Delphi, or C# are not directly supported, but can be used through a 'wrapper'. C-Script was the standard scripting language of Gamestudio. A new script language, lite-C, will be additionally available in future versions. It is extremely  similar to C-Script - in fact you won't see a difference at a first glance. However at a second glance it offers far more possibilities, so this will your language of choice for new projects as soon as it's available.

Unlike C-Script, lite-C can be used in two modes: Pure Mode and Legacy Mode. Pure mode code is a lot simpler and shorter. It uses the functions of the acknex engine, and does not require programming a window and a message loop. In Windows mode the engine functions are not available. Windows mode code however can be compiled with any C++ compiler as long as only standard C features are not used.

Feature
C-Script
lite-C Pure
lite-C Legacy
C
C++
Standard extension
.wdl
.c
.c
.c
.cpp
Main function
main()
main()
WINAPI WinMain(...)
WINAPI WinMain(...)
WINAPI WinMain(...)
Case sensitive no yes yes yes yes
Standard variables
var
var, int, long, short, char, float, double
var, int, long, short, char, float, double
int, long, short, char, float, double

int, long, short, char, float, double

Structs
predefined only
yes
yes
yes
yes
Classes
no
no
no
no
yes
Function overloading
no
yes
yes
no
yes
COM+ support no
yes
yes
yes
yes
DLL support plugins only
yes
yes
yes
yes
Struct autoinitialisation*
yes
yes
yes
no
no
Pointer autodetection*
yes
yes
yes
no
no
Control functions if, while if, while, for, do, switch if, while, for, do, switch if, while, for, do, switch if, while, for, do, switch
Code compilation on-the-fly on-the-fly and in advance on-the-fly and in advance in advance only in advance only

* Struct autoinitialisation and pointer autodetection are features that greatly simplify program code. The compiler automatically deals with object creation and memory allocation, and handles pointers just like their contents. This removes most complicated and formal stuff from the language.

Below you'll find two examples of a Mandelbrot script written in Pure and Legacy mode. As you see, in Pure Mode the program consists almost only of the functions that draw the Mandelbrot fractal. All stuff unrelated to the program goal, like creating a window and handling a message loop, is automatically dealt with by the compiler.

lite-C Pure Mode lite-C Legacy Mode, C, or C++
#include <acknex.h> // Pure Mode
////////////////////////////////////////////////////////// // Draw a Mandelbrot fractal. double m_x = 0.344142, m_y = 0.075094, m_width = 0.017813; long JetColor(double v) { double d = 25.0; v = v/d + 0.5; int i = (int)v; int f = (int)(255*(v-i)); int r=0, g=0, b=0; switch(i) { case 0: r=0; g=0; b=f; break; case 1: r=0; g=f; b=255; break; case 2: r=f; g=255; b=255-f; break; case 3: r=255; g=255-f;b=0; break; case 4: r=255-f;g=0; b=0; break; } return (255<<24)|(r<<16)|(g<<8)|b; } void Draw(BMAP* bmap) { var w = bmap_width(bmap); var h = bmap_height(bmap); var i,j; var times,inset; double x,y,zx,zy,zxs,zys; long detail=100; bmap_lock(bmap); for(i=0;i<w;i++) for(j=0;j<h;j++) { x = m_x+((double)i)*m_width/w; y = m_y+((double)(h-j))*m_width/w; zx = 0; zy = 0; inset = 1; times = 0; while(inset && times<detail) { times++; zxs = zx*zx; zys = zy*zy; zy = 2*zx*zy+y; zx = zxs-zys+x; if (zxs+zys >= 4.0) inset=0; } if(inset) pixel_to_bmap(bmap,i,j,255<<24); else pixel_to_bmap(bmap,i,j,JetColor(times)); } bmap_unlock(bmap); } ////////////////////////////////////////////////////////// // Define the panel that carries the image PANEL* mandel_panel = { } // Left mouse button clicked somewhere on the image. // Zoom in by 0.5, calculate a new position, and draw. void mandel_click() { double a; a = mouse_cursor.x; a /= screen_size.x; m_x += m_width*(a-0.5); a = mouse_cursor.y; a /= screen_size.y; m_y += m_width*(0.5-a); m_width *= 0.5; Draw(mandel_panel->bmap); } void main() { // Create a bitmap, screen sized, for the panel background. mandel_panel.bmap = bmap_createblack(screen_size.x,screen_size.y,8888); // make the panel visible on screen mandel_panel.flags |= SHOW; // don't draw before the D3D device is created wait(1); // Now we can draw Draw(mandel_panel.bmap); // Set a mouse event for redrawing the image on_mouse_left = mandel_click; }
#include <litec.h> // Legacy Mode

/////////////////////////////////////////////////////////
// Draw a Mandelbrot fractal. 
double m_x = 0.344142,
  m_y = 0.075094,
  m_width = 0.017813;

long JetColor(double v)
{
   double d = 25.0;
   v = v/d + 0.5;
   int i = (int)v;
   int f = (int)(255*(v-i));
   int r=0, g=0, b=0;

   switch(i) {
     case 0: r=0; g=0; b=f; break;
     case 1: r=0; g=f; b=255; break;
     case 2: r=f; g=255; b=255-f; break;
     case 3: r=255; g=255-f;b=0; break;
     case 4: r=255-f;g=0; b=0; break;
   }
   return r|(g<<8)|(b<<16);
}

void Draw(HDC hdc,long vw,long vh)
{
   long w = vw;
   long h = vh;
   long i,j;
   long times,inset;
   double x,y,zx,zy,zxs,zys;
   long detail=100;
   
   for(i=0;i<w;i++)
   for(j=0;j<h;j++)
   {
     x = m_x+((double)i)*m_width/w;
     y = m_y+((double)(h-j))*m_width/w;
     zx = 0;
     zy = 0;
     inset = 1;
     times = 0;
     while(inset && times<detail)
     {
       times++;
       zxs = zx*zx;
       zys = zy*zy;
       zy = 2*zx*zy+y;
       zx = zxs-zys+x;
       if (zxs+zys >= 4.0) inset=0;
     }
     if(inset)
       SetPixel(hdc,i,j,0);
     else
       SetPixel(hdc,i,j,JetColor(times));
   }
}

////////////////////////////////////////////////////////
// message loop function
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, 
                         WPARAM wParam, LPARAM lParam)
{
   PAINTSTRUCT ps;
   HDC hdc;
   switch(message) {
 
 case WM_LBUTTONDOWN:
// zoom in at cursor position
   {
   RECT rect;
   GetClientRect(hWnd,&rect);
   long x = ((long)lParam)&0xffff;
   long y = (((long)lParam)&0xffff0000)>>16;
   double a;
   a = x; a /= rect.right; m_x += m_width*(a-0.5);
   a = y; a /= rect.bottom; m_y += m_width*(0.5-a);
   m_width *= 0.5;
   InvalidateRect(hWnd,0,0);
   }
   break;

 case WM_DESTROY:
   PostQuitMessage(0);
   break;

 case WM_COMMAND:
   switch(wParam){
   case 1:
   m_x=-2.5;
   m_y=-2;
   m_width=4.0;
   InvalidateRect(hWnd,0,0);
   break;
   case 2:
   break;
   case 3:
   PostMessage(hWnd, WM_CLOSE,0,0);
   break;
   }
   break;

case WM_PAINT:
   hdc = BeginPaint(hWnd, &ps);
   RECT rect;
   GetClientRect(hWnd,&rect);
   Draw(hdc,rect.right,rect.bottom);
   EndPaint(hWnd, &ps);
   break;
   case WM_KEYDOWN:
   switch( wParam )
   {
     case VK_ESCAPE:
     case VK_F12:
     PostMessage(hWnd, WM_CLOSE,0,0);
     break;
   }
   break;

 default:
   return DefWindowProc(hWnd, message, wParam, lParam);
 }
 return 0;
}

int WINAPI WinMain (WINARGS)
{
//Create a window
   char *szClass = "liteCWindowClass";
   HINSTANCE hi = GetModuleHandle(NULL);
   UnregisterClass(szClass,hi);
   WNDCLASSEX wcex;
   wcex.cbSize = sizeof(WNDCLASSEX);
   wcex.style	= CS_HREDRAW|CS_VREDRAW;
   wcex.lpfnWndProc	= WndProc;
   wcex.cbClsExtra	= 0;
   wcex.cbWndExtra	= 0;
   wcex.hInstance	= hi;
   wcex.hIcon	= LoadIcon(hi,(LPCSTR)128);
   wcex.hCursor	= LoadCursor(NULL, IDC_ARROW);
   wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
   wcex.lpszMenuName	= NULL;
   wcex.lpszClassName	= szClass;
wcex.hIconSm = LoadIcon(hi,(LPCSTR)128);
RegisterClassEx(&wcex);
HWND hwnd=CreateWindowEx(0,szClass,
"Mandelbrot",0x96cf0000,0,0,640,480,NULL,0,NULL,NULL);
// create a menu HMENU menu = CreateMenu(); HMENU hSubMenu = CreateMenu(); InsertMenu(hSubMenu,0,MF_BYPOSITION|MF_STRING,1,"Reset"); InsertMenu(hSubMenu,2,MF_BYPOSITION|MF_STRING,3,"Quit"); InsertMenu(menu,0,MF_BYPOSITION|MF_STRING|MF_POPUP, (UINT_PTR)hSubMenu,"File"); // activate window, menu, and message loop if (hwnd) { SetMenu(hwnd,menu); ShowWindow(hwnd,SW_SHOW); MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return 0; }
► latest version online