Gamestudio Links
Zorro Links
Newest Posts
ZorroGPT
by TipmyPip. 10/06/26 05:32
Purchase A8 full licence version
by jcl. 10/05/26 12:12
Respect History setting for Z systems
by AndrewAMD. 10/02/26 15:43
AUM Magazine
Latest Screens
Dorifto samurai
Shadow 2
Rocker`s Revenge
Stug 3 Stormartillery
Who's Online Now
0 registered members (), 14,965 guests, and 2 spiders.
Key: Admin, Global Mod, Mod
Newest Members
JimSimons, julienp, julienper, KelleyAbbey, Yopachi
19246 Registered Users
Active Threads | Active Posts | Unanswered Today | Since Yesterday | This Week
Starting with Zorro
Yesterday at 05:32
Enjoy, and Improve the Strategy.
259 98,179 Read More
Zorro and the Brokers
10/05/26 16:36
Contact support for this. They can be reached here:
support@opgroup.de
1 35 Read More
Zorro and the Brokers
10/05/26 15:15
I have purchased a monthly subscription for Zorro, but I didn't receive any subscription key to activate it.

May I know how to proceed? Thanks.
1 35 Read More
Starting with Gamestudio
10/05/26 12:12
You'll get a license key that unlocks the A8 demo version to a full version.
10 1,744 Read More
Starting with Zorro
10/05/26 12:02
I readily believe that you get gaps and bad results with your settings. Unless you trade on the Moscow stock exchange, better use the default weekend and time zone for currencies. Their weekend begins with market close in New York and ends at market open in Sydney. Even if your broker has weekend bars of currencies, they are not from regular trading, and better don't use them for a strategy.
1 127 Read More
Zorro Scripts
10/03/26 14:42
// ---- Real-trade scan buffers: rebuilt every bar, nothing carried ---- [R-33]
#define SCAN_NA 16 // [R-33] max assets in the list
#define SCAN_W 4 // [R-33] events kept per asset and bar
int ScanFillN[SCAN_NA], ScanClsN[SCAN_NA];
var ScanFillID[64], ScanFillDir[64], ScanFillPx[64]; // [R-33] 64 = SCAN_NA * SCAN_W
var ScanClsID[64], ScanClsPx[64];
int FltBars = 0, FltGreen = 0; // [R-22] filter census, trace only

// [R-33] Index of an asset in the list, -1 if absent.
int scanIdx(string Name)
{
int i;
for(i = 0; i < NumAssetsListed; i++)
if(strcmp(Name, Assets[i]) == 0) return i;
return -1;
}

// [R-33] Slot of this bar's fill on asset k in direction Dir, -1 if none.
int scanFill(int k, int Dir)
{
int j;
for(j = 0; j < ScanFillN[k]; j++)
if(j < SCAN_W && ScanFillDir[k*SCAN_W + j] == Dir) return j;
return -1;
}

// [R-33] Slot of this bar's close of trade ID on asset k, -1 if none.
int scanCls(int k, var ID)
{
int j;
for(j = 0; j < ScanClsN[k]; j++)
if(j < SCAN_W && ScanClsID[k*SCAN_W + j] == ID) return j;
return -1;
}

// [R-28] Classify a closed signal by its move before costs, signed by direction.
// [R-28] A move of exactly zero changes nothing.
void classify(vars PrevLoss, vars HaveHist, int Dir, int How, var Move)
{
printf("\n@SIG,%s,%i,%i,%i,%.8f", Asset, (int)Bar, Dir, How, (var)Move); // [R-28] trace
if(Move < 0) { PrevLoss[0] = 1; HaveHist[0] = 1; }
else if(Move > 0) { PrevLoss[0] = 0; HaveHist[0] = 1; }
}

function run()
{
// ---- Engine / mode setup ---------------------------------- [R-01..R-05]
BarPeriod = 1440; // [R-01] daily bars
BarOffset = 940; // [R-01] bar starts 15:40 in the bar time zone
set(LOGFILE); // [R-03] export logs and statistics files
set(TICKS); // [R-02] tick-precise intrabar simulation (D021)
Verbose = 3; // [R-03] skipped trades + parameter errors
// !! [R-03] Warning 047 verbosity is OBSERVED, not documented -- see 3.1.

// ---- Data source ------------------------------------------------ [R-04]
// !! [R-04] '*' reads the year files but keeps Zorro's silent bare-file
// !! fallback; the AssetFirstBar preflight below is the only control on it.
History = "put your \\Zorro\\History\\*.t6"; // [R-04]
NumYears = 20; // [R-05] simulation window
EndDate = 20261001; // [R-05] window end pinned (D029 Add. 3)

// ---- Parameter block -------------- [R-07, R-08, R-24, R-26, R-27, R-31]
int EntryDays = 20; // [R-07] System 1 entry channel, trading days
int ExitDays = 10; // [R-07] System 1 exit channel, trading days
int FailDays = 55; // [R-07] failsafe entry channel, trading days
int NPeriod = 20; // [R-26] N = average true range over 20 days
var StopMult = 2.0; // [R-27] hard stop at 2N from the fill price
int BreakTicks = 1; // [R-08] strict break: price increments beyond the level

// ---- Warm-up ---------------------------------------------- [R-09, R-26]
LookBack = 70; // [R-09] covers 55-day channel and 20-day N
UnstablePeriod = 40; // [R-26] recursive TA-Lib indicators re-run over 40 bars

// ---- Order handling ------------------------------------- [R-10..R-13]
EntryTime = 2; // [R-11] pending order lifetime, bars. INERT (see R-18)
Fill = 2; // [R-12] alternative order filling (D023)
Hedge = 0; // [R-13] netting by ASSET, not by algo

// ---- Universe --------------------------------------------------- [R-06]
if(is(INITRUN))
assetList("AssetsDryRunP7"); // [R-06] frozen P7 (D019)

MaxLong = 1; // [R-10] one position per side per asset
MaxShort = 1; // [R-10] magnitude live, sign inert (see R-18)

// ---- Real-trade scan: this bar's fills and closes ------------- [R-33]
// [R-33] Above the asset loop: enumeration loops cannot be nested.
int si, sk, ss;
for(si = 0; si < SCAN_NA; si++) { ScanFillN[si] = 0; ScanClsN[si] = 0; }
for(past_trades) {
if(TradeID != 0) {
sk = scanIdx(TradeAsset);
if(sk >= 0) {
// !! [R-33] TradeInt is 0 on a new trade: OBSERVED, not documented.
if(TradeInt[15] == 0) { // [R-33] fill not seen yet
TradeInt[15] = 1;
if(ScanFillN[sk] < SCAN_W) {
ss = sk*SCAN_W + ScanFillN[sk];
ScanFillID[ss] = TradeID; ScanFillDir[ss] = ifelse(TradeIsLong, 1, -1);
ScanFillPx[ss] = TradePriceOpen;
}
ScanFillN[sk] += 1;
}
if(TradeIsClosed && TradeInt[14] == 0) { // [R-33] close not seen yet
TradeInt[14] = 1;
if(ScanClsN[sk] < SCAN_W) {
ss = sk*SCAN_W + ScanClsN[sk];
ScanClsID[ss] = TradeID; ScanClsPx[ss] = TradePriceClose;
}
ScanClsN[sk] += 1;
}
}
}
}
if(is(EXITRUN))
printf("\n@FGR,%i,%i", FltGreen, FltBars); // [R-22] filter census, trace only

for(listed_assets)
{
// [R-25] for(listed_assets) only assigns Asset; it does not select.
if(!asset(Asset)) continue;

// [R-04] Reject any asset whose history does not cover the window.
if(AssetFirstBar > 0) {
printf("\n SKIP %s -- history starts at bar %i/%i",
Asset, (int)AssetFirstBar, (int)NumBars);
continue;
}

// [R-08] Read PIP inside the loop: it is an asset-specific parameter.
var BreakOffset = BreakTicks * PIP;

// ---- Price series ------------------------------------------------
vars H = series(priceHigh());
vars L = series(priceLow());

// ---- Rolling trading-day channels ------------------ [R-15, R-25]
// [R-25] Per-asset state lives in series(), NEVER in a bare static.
// [R-15] Carried as series so the code can read the level that was
// actually RESTING during a given bar -- see R-16.
vars ChEntryHigh = series(0), ChEntryLow = series(0);
vars ChExitLow = series(0), ChExitHigh = series(0);
vars ChFailHigh = series(0), ChFailLow = series(0);

ChEntryHigh[0] = MaxVal(H, EntryDays); // 20-day high
ChEntryLow[0] = MinVal(L, EntryDays); // 20-day low
ChExitLow[0] = MinVal(L, ExitDays); // 10-day low
ChExitHigh[0] = MaxVal(H, ExitDays); // 10-day high
ChFailHigh[0] = MaxVal(H, FailDays); // 55-day high
ChFailLow[0] = MinVal(L, FailDays); // 55-day low

// ---- Volatility primitive N -------------------------------- [R-26]
vars N = series(ATR(NPeriod));

// ---- Warm-up counter ---------------------------------------- [R-09]
vars BarsSeen = series(0);
BarsSeen[0] = BarsSeen[1] + 1;

// ---- Shadow-tracker series -------------------- [R-22, R-25, R-28]
// [R-25] Created ABOVE the warm-up gate: series() calls must never be
// skipped by a bar-varying condition. Only their [0] elements are set
// conditionally, further down.
vars ShDir = series(0); // shadow signal: 0 none, +1 long, -1 short
vars ShEntry = series(0); // shadow entry price (level + break offset)
vars ShAdv = series(0); // [R-28] the 2N adverse level, fixed at signal
vars PrevLoss = series(0); // 1 = last CLOSED shadow signal was a loser
vars HaveHist = series(0); // 1 = at least one shadow signal has closed

ShDir[0] = ShDir[1];
ShEntry[0] = ShEntry[1];
ShAdv[0] = ShAdv[1];
PrevLoss[0] = PrevLoss[1];
HaveHist[0] = HaveHist[1];

// ---- Real-trade link series ---------------------------- [R-33, R-25]
vars TrkID = series(0); // [R-33] real trade tied to the open signal, 0 none
vars PlL = series(0); // [R-33] 1 = a 20-day long entry rested this bar
vars PlS = series(0); // [R-33] 1 = a 20-day short entry rested this bar
TrkID[0] = TrkID[1];

// [R-09] Warm-up gate. Every series() call for this asset is ABOVE it.
if(BarsSeen[0] < 70) continue;

// ---- Level-or-distance preflight -------------------- [R-17, R-32]
var HalfPrice = 0.5 * priceClose();
bool badEntryHigh = (ChEntryHigh[0] < HalfPrice);
bool badEntryLow = (ChEntryLow[0] < HalfPrice);
bool badExitLow = (ChExitLow[0] < HalfPrice);
bool badExitHigh = (ChExitHigh[0] < HalfPrice);
bool badFailHigh = (ChFailHigh[0] < HalfPrice);
bool badFailLow = (ChFailLow[0] < HalfPrice);
bool badStopDist = (StopMult * N[0] >= HalfPrice);

if(badEntryHigh || badEntryLow || badExitLow || badExitHigh || badFailHigh || badFailLow)
printf("\n!!! %s bar %i: channel level below half the asset price %.5f (EntryHigh %.5f, EntryLow %.5f, ExitLow %.5f, ExitHigh %.5f, FailHigh %.5f, FailLow %.5f) -- Zorro reads such a value as a DISTANCE, not a level (stop.htm).",
Asset, (int)Bar, (var)HalfPrice, (var)ChEntryHigh[0], (var)ChEntryLow[0],
(var)ChExitLow[0], (var)ChExitHigh[0], (var)ChFailHigh[0], (var)ChFailLow[0]);
if(badStopDist)
printf("\n!!! %s bar %i: 2N stop distance %.5f is at or above half the asset price %.5f -- Zorro would read it as a LEVEL, not a distance (stop.htm).",
Asset, (int)Bar, (var)(StopMult * N[0]), (var)HalfPrice);
// [R-32] Exit levels are NOT gated -- suppressing an exit removes protection.
if(badExitLow || badExitHigh)
printf("\n@XLV,%s,%i,%.8f,%.8f,%.8f", Asset, (int)Bar,
(var)ChExitLow[0], (var)ChExitHigh[0], (var)HalfPrice);

// ---- One-bar order-placement lag -------------------------- [R-16]
// [R-16] Convention: every TEST reads [1], every ORDER is placed with [0].
var RestEntryHigh = ChEntryHigh[1];
var RestEntryLow = ChEntryLow[1];
var RestExitLow = ChExitLow[1];
var RestExitHigh = ChExitHigh[1];
var RestFailHigh = ChFailHigh[1];
var RestFailLow = ChFailLow[1];
var RestN = N[1];

// [R-08] Entry breaks are STRICT: the offset is in the test and in the
// order, so shadow and real fill on the same bar at the same price.
bool hitEntryHigh = (H[0] >= RestEntryHigh + BreakOffset);
bool hitEntryLow = (L[0] <= RestEntryLow - BreakOffset);
// [R-20] Exit stops are taken AT the level -- the break rule is on entries.
bool hitExitLow = (L[0] <= RestExitLow);
bool hitExitHigh = (H[0] >= RestExitHigh);

// ---- Shadow signal bookkeeping ---------- [R-22, R-28, R-21, R-33]
int ScanK = scanIdx(Asset); // [R-33]
int RealClosed = 0, Slot = -1, FillSlot = -1, OpenDir = 0;
var RealExit = 0, Rested20 = 0;
if(TrkID[0] != 0) {
Slot = scanCls(ScanK, TrkID[0]);
if(Slot >= 0) { RealClosed = 1; RealExit = ScanClsPx[ScanK*SCAN_W + Slot]; }
}
int ShStart = ShDir[0]; // [R-22] shadow state at bar start
if(ShStart != 0 && TrkID[0] != 0)
{
// [R-33] A taken breakout closes with its real trade, never on the shadow tests.
if(RealClosed) {
classify(PrevLoss, HaveHist, ShStart, 3, (RealExit - ShEntry[0]) * ShStart);
ShDir[0] = 0;
}
}
else if(ShStart > 0)
{
// [R-28] 2N adverse excursion tested BEFORE the 10-day exit.
if(L[0] <= ShAdv[0]) {
classify(PrevLoss, HaveHist, 1, 1, ShAdv[0] - ShEntry[0]);
ShDir[0] = 0;
} else if(hitExitLow) {
classify(PrevLoss, HaveHist, 1, 2, RestExitLow - ShEntry[0]);
ShDir[0] = 0;
}
}
else if(ShStart < 0)
{
if(H[0] >= ShAdv[0]) {
classify(PrevLoss, HaveHist, -1, 1, ShEntry[0] - ShAdv[0]);
ShDir[0] = 0;
} else if(hitExitHigh) {
classify(PrevLoss, HaveHist, -1, 2, ShEntry[0] - RestExitHigh);
ShDir[0] = 0;
}
}
if(RealClosed) TrkID[0] = 0;
if(ShStart == 0)
{
// [R-21] Outside-bar tie-break: long tested first, deterministically.
if(hitEntryHigh) OpenDir = 1;
else if(hitEntryLow) OpenDir = -1;
// [R-22] No same-bar close: a shadow opened here is tested from
// the NEXT bar.
}
else if(ShDir[0] == 0) // [R-22] closed on this bar
{
// [R-22] An OPPOSITE break on the closing bar opens a new signal.
if(ShStart > 0 && hitEntryLow) OpenDir = -1;
else if(ShStart < 0 && hitEntryHigh) OpenDir = 1;
}
if(OpenDir != 0)
{
ShDir[0] = OpenDir;
if(OpenDir > 0) ShEntry[0] = RestEntryHigh + BreakOffset;
else ShEntry[0] = RestEntryLow - BreakOffset;
ShAdv[0] = ShEntry[0] - OpenDir * StopMult * RestN; // [R-28]
// [R-33] Taken: a same-direction fill this bar, from a 20-day order rested last bar.
FillSlot = scanFill(ScanK, OpenDir);
Rested20 = PlS[1];
if(OpenDir > 0) Rested20 = PlL[1];
if(FillSlot >= 0 && Rested20 == 1) {
TrkID[0] = ScanFillID[ScanK*SCAN_W + FillSlot];
ShEntry[0] = ScanFillPx[ScanK*SCAN_W + FillSlot]; // [R-33] the real fill
Slot = scanCls(ScanK, TrkID[0]);
if(Slot >= 0) {
// [R-33] The real trade also closed on its fill bar.
classify(PrevLoss, HaveHist, OpenDir, 3, (ScanClsPx[ScanK*SCAN_W + Slot] - ShEntry[0]) * OpenDir);
ShDir[0] = 0;
TrkID[0] = 0;
}
}
}

// ---- Previous-signal filter ------------------------ [R-22, R-23]
// [R-22] Read AFTER this bar's shadow update.
// [R-23] First signal on each asset is taken: there is no previous one.
bool filterOK = (HaveHist[0] == 0) || (PrevLoss[0] > 0);
FltBars += 1; if(filterOK) FltGreen += 1; // [R-22] census, trace only

// ---- Real orders ---- [R-14, R-18..R-21, R-27, R-29..R-32]
if(NumOpenLong > 0)
{
// [R-19] Cancel the opposite pending order left alive by the fill.
exitShort(0);
// [R-20, R-30] Ratcheted 10-day channel exit, re-issued each bar at
// the current level; it can only tighten. [R-27] the 2N stop stays
// attached and the nearer of the two closes the trade.
exitLong(0, ChExitLow[0]);
}
else if(NumOpenShort > 0)
{
exitLong(0);
exitShort(0, ChExitHigh[0]);
}
else
{
// [R-18] Cancel yesterday's unfilled orders, then re-place fresh.
// Reached ONLY when flat -- the branch structure IS the guard.
exitLong(0);
exitShort(0);

Stop = StopMult * N[0]; // [R-27] 2N hard stop, a DISTANCE to the fill price

// [R-29] Filter green: the 20-day levels. Filter red: the 55-day failsafe.
var LongLevel = ChEntryHigh[0];
var ShortLevel = ChEntryLow[0];
bool badLong = badEntryHigh;
bool badShort = badEntryLow;
if(!filterOK) {
LongLevel = ChFailHigh[0]; badLong = badFailHigh;
ShortLevel = ChFailLow[0]; badShort = badFailLow;
}

// [R-14] Family B: resting stop orders AT the level, not close tests.
// [R-08] Entry carries the break offset.
// [R-32] An order the engine would misread is suppressed, per side.
if(badLong || badStopDist)
printf("\n@SUP,%s,%i,L,%.8f,%.8f,%.8f", Asset, (int)Bar,
(var)LongLevel, (var)HalfPrice, (var)(StopMult * N[0]));
else {
enterLong(1, LongLevel + BreakOffset);
PlL[0] = filterOK; // [R-33] 1 = rested at the 20-day level
}

if(badShort || badStopDist)
printf("\n@SUP,%s,%i,S,%.8f,%.8f,%.8f", Asset, (int)Bar,
(var)ShortLevel, (var)HalfPrice, (var)(StopMult * N[0]));
else {
enterShort(1, ShortLevel - BreakOffset);
PlS[0] = filterOK; // [R-33] 1 = rested at the 20-day level
}
}
}
}
6 2,291 Read More
RangerZ & Z Systems
10/02/26 15:43
It works for me.

Two questions:
1. You did set the HistoryFolder value, correct?
2. You still have your asset and account lists in the original History folder, correct?

Documented here:
https://zorro-project.com/manual/en/ini.htm
1 108 Read More
RangerZ & Z Systems
10/02/26 11:36
I tried setting History in z.ini but found it has not effect.

Would be great to have it working.
1 108 Read More
Starting with Zorro
10/02/26 03:36
Hi,

I'm reproducing Alice1 from the Black Book (EUR/USD, H1, 2016-2026, price history from the Zorro site, Zorro 3.11.2). With the original script I get roughly the book's result (PF around 1.4).

On the chart, there is a gap of exactly 3 hourly bars after the weekend open: these 3 bars are missing and seem to be merged into the next bar, although every broker I checked shows them.

I added BR_WEEKEND with StartWeek/EndWeek (and BarZone) to make those 3 bars reappear, so the bars match my broker (Darwinex/MT5). With otherwise the same logic, the result changes a lot: PF drops to about 1.1 with a much less regular equity curve. Removing only the weekend lines brings back the book's result.

The effect seems even stronger on higher timeframes, for example H4, where the first bar after the weekend is clearly distorted without these settings.

So my question: is this expected? Are those weekend bars skipped on purpose by default (to keep the example simple, or because those hours are illiquid), or am I doing something wrong in my setup? This is the script I used:

Code
function run()
{
  set(LOGFILE,PLOTNOW,PRELOAD);
  Fill = 3;
  Outlier = 0;
  LookBack = 1000;

  BarZone = 2;             // match broker bars (Darwinex/MT5)
  BarMode = BR_WEEKEND;
  StartWeek = 10000;       // Monday 00:00
  EndWeek = 60000;         // Saturday 00:00

  StartDate = 20160101;
  EndDate = 20260201;
  MaxLong = MaxShort = 1;

  vars Prices = series(price());
  vars Trends = series(Laguerre(Prices,0.05));
  vars MMI_Raws = series(MMI(Prices,500));
  vars MMI_Avgs = series(Laguerre(MMI_Raws,0.05));

  Stop = 10*ATR(500);
  Lots = 1;

  if(falling(MMI_Avgs)) {
    if(valley(Trends))
      enterLong();
    else if(peak(Trends))
      enterShort();
  }
}


Asset EUR/USD and bar period 60 are selected in the Zorro window. Screenshot of the gap attached.

Thanks!
1 127 Read More
Starting with Gamestudio
10/02/26 01:31
That's good for me then with PayPal. I only asked about the source as the website appears a little dated and wanted to make sure that
nothing had changed over the years. I'm currently using a Delphi API library and using C++ A7 SDK and now want to update to the A8 SDK.
So, I need as much source code as possible.

One further question. How is the Pro SDK version delivered ? I do not have a Github or Discord account.

Many Thanks.
10 1,744 Read More
Bug Hunt
09/30/26 18:35
If you use the default TradeTest.c script as-is with Interactive Brokers, it will not work. Here's why.

This line of code is the culprit:
Code
if(is(INITRUN)) brokerCommand(SET_ORDERTEXT,"TradeTest");


This of course looks like it would add a mere comment to a placed order. But that's not what happens with IB in particular.

Instead, it sets the IB order's OrderType string value, which is a critical field. So if the order type is set to "TradeTest", the test order won't work.

I expect that most newcomers to Zorro would not be able to figure this out without running the script in verbose mode and then debugging the script.

Before I remove the line:
Code
!Open IB Socket 4.03 at UTC 09-30 17:39
 ESZ6
 ESZ6

Trade: TradeTest ESZ6 2026-09-30
Assets AssetsFutures
 ESZ6
Buy Long ESZ6
!Order 4137 ES-FUT-ESZ6-ES-CME BUY TradeTest DAY 2 ES-FUT--0.00--CME/-ES-USD
!Error validating request.-'v' : cause - Invalid order type was entered ES-FUT--0.00--CME/-ES-USD
!Order rejected: error validating request.-'v' : cause - invalid order type was entered
Warning 075 (ESZ6::L) - can't open 2@7762 at 17:39:24

After I remove the line:
Code
!Open IB Socket 4.03 at UTC 09-30 17:39
 ESZ6
 ESZ6

Trade: TradeTest ESZ6 2026-09-30
Assets AssetsFutures
 ESZ6
Buy Long ESZ6
!Order 4147 ES-FUT-ESZ6-ES-CME BUY MKT DAY 2 ES-FUT--0.00--CME/-ES-USD
[ESZ6::L04147] Long 2@7763.50  at 17:42:45
4147: Lots 2 Target 2 Open 7763.50000 Close 7763.50000
4147: Lots 2 Target 2 Open 7763.50000 Close 7763.75000


Note that "TradeTest" gets replaced with "MKT" (market order).
0 29 Read More
Shaders
09/29/26 18:12
Small Update

My starter reads the values from the engine starter like the progressbar etc and displays them on the loading screen. laugh

Even outside of lite-c acknex fights back...it is a witch work to get the percentage of the "8bit" old school starter window. it only works with Tricks
(Width measurement) because Conitec used a custom class "class_WrProgress - the most efficient way possible".


Now iam trying to do the same thing for the text, so i can directly read the start infos like cancel etc to react even more stable to engine start events.


edit:
I can really only chuckle at this point... everything in Acknex always puts up a fight XD ...even the measly starter text from the custom "class_wrTextF" can't be read out via message hook or RAM sniffing...crazy XD
...okay, so the only option left is "acklog sniffing." Thank god i can get the percentage from the starter...

edit
If "Diagnose" ist checked in the starter it shows the starter text on the loading info. I gave up on class_wrTextF and grab it from acklock.txt instead.



edit
Danger! I have rewritten the logic. my starter is now in control of the exec. i thought what happens if a faster pc want to go in fullscreen while the old engine just going out of fullscreen?
Thats not good laugh ...so my starter shows the loadings screen, waits for the process to finish plus a few seconds and then starts the new engine.
another edit: Ok it works now. But now im going back to do the exec from engine laugh ...but this time i simply switch in window mode before exit.
Since i can feed and show a progress bar from engine starters progress i "hide" the starter window in window mode on swap via -nwnd (so its still in the task bar if user wants to see details. In "diagnose mode" it shows acklog text like i mentioned).
152 279,234 Read More
Starting with Gamestudio
09/29/26 09:37
Only the source code of the included scripts, not of the engine. There are examples of using the SDK. The purchase link is for credit card payment, but you can order by email to Support if you want to pay with Paypal.
10 1,744 Read More
Shaders
09/29/26 00:52
So i have implemented the "dirty hack"...i have to say...it looks good and works like a charm.
(Engine swap means it reloads itself with other content/same content, not another acknex exe)

Its done via a created file and intern exec. my own starter app checks for this file. if it does exist it shows a loading screen to hide the engine swap.
i also made a security timer, if starter crashes, it removes the loading screen. if user press ESC or click the screen its removed (showing the engine start window if it still exists).
So its "soft hidden" not "malware style" (while progging i locked my desktop XD ...good i had my second screen on).
In window mode it just adds a loading info on top of the engine starter window while still showing it. The engine start window is modified to match the starter app's look.
In fullscreen mode it fills the desktop in black color with a loading info label on top to hide the engines fullscreen switch. Before i exit the game i fade into a black screen,
desktop is already black, new game loads in and fades the black screen out.
If the starter detects an engine swap interruption, it asks the user whether they want to try reloading or not.

The cool thing is, it reloads very quick. only the first start / loading of WRS takes a bit longer.
This engine swap is almost invisible to the user and stable (as long as engine has read/write access on hd...and starter checks for this before starting the game).

This way every click on new games "cleans" the memory so the game can run for ever laugh
And use a lot of content in theory...

I use this starter since Dead Taste anyway, so it's another nice feature.
Starter combines installation (downloading and/or installing of physicX etc), game and video settings and the game launch itself.
A single START.exe with a sub folder (engine files WRS etc).
152 279,234 Read More
Starting with Gamestudio
09/28/26 18:57
[video:youtube]https://youtu.be/P0ZzwiDSnsg?is=6x1x9l1_D576-PLw[/video]

Wed bekomme ich nochnicht ans rennen egal mehr wollte ich nie
4 271 Read More
The Past
09/28/26 17:04
Well, I'm digging for more open wdl files. I'm hoping to become fluent enough in A3 WDL to make a youtube video about it. Firoball seems to have done some deep diving and preservation of the software but I dont know how to contact @fbl seems like he was last on the forums 5 years ago
50 30,144 Read More
Starting with Gamestudio
09/28/26 10:17
What source code is included with the Pro A8 and are there any tutorials or guides on how to use the A8 SDK ?
10 1,744 Read More
Starting with Gamestudio
09/28/26 09:53
Med rennt auch jetzt smile
Hier die einstellung
[img]https://ibb.co/zHQb8Cqd[/img]
4 271 Read More
The Past
09/27/26 20:38
Same here laugh
the room is full of action figures (most of them vintage) in original package but only a few boxes. grin
But i can feel the urge of collectim them...i want a duke nukem big box, the first no atomic or something like that...200-300€! Nah...

[Linked Image]
My HellCab is on ebay over two years now.

Btw links to old a3 stuff would be cool yes.
50 30,144 Read More
The Past
09/27/26 20:12
I always wanted to know what was on the box! I have a few big boxes. Not a library or anything
[Linked Image]
50 30,144 Read More
The Past
09/27/26 19:23
Yes i love old games too and the boxes. i have a small collection in my game room with old pc bix box games. kingpin, ghostbusters II, willy beamish etc laugh
And yes this package is indeed a beauty. I was a "kid" when i bought it.

[Linked Image]
[Linked Image]

Conitec history.
50 30,144 Read More
The Past
09/27/26 18:47
That box is a thing of beauty!!! I do have the commercial release files. There was a long list of projects that were linked and re-linked above. They are dead links now. Thanks for indulging my necromancy with your reply. I love games and game tool preservation.
50 30,144 Read More
Starting with Gamestudio
09/27/26 14:43
"Map entities" might work for you. A collection of entites / blocks in a WMB file loaded via ent_create (if you jiust want to "combine" static models but not moving)


If not:
Code
#define anm_frame  skill80

var level_loading = 0;

action Actor_with_Gun_WED(){
   while (my && level_loading) wait (1); // wait for level loading is done!
   ENTITY* ent = ent_create("gun.mdl", vector(0,0,0), NULL); // create gun entity without action
 //if (!ent){ safe_remove (me; return; }
  
   while(my && !level_loading){
    //if (!freeze_mode){   
      my.anm_frame += time_step;
      my.anm_frame %= 100;
      ent_animate(me, "walk", my.anm_frame, ANM_CYCLE);
      if (ent){ // always check for valid pointers
         //attach gun to "RightHand" bone
         vec_for_bone(ent.x, my, "RightHand"); // move gun entity
       //vec_for_vertex (ent.x, my, "123");
         ang_for_bone(ent.pan, my, "RightHand"); // rotate entity
      }
    //}
      wait(1);
   }
 //wait(1);//super safe XD
   if (ent){
      safe_remove (ent);
      //ent = NULL;  // global pointers only
   }
   safe_remove (me);
}

...

// safe level switch "no matter what"
level_loading = 1;
wait (-1);
level_load ("map2.wmb");
wait (5);
level_loading = 0;

...


"safe" global entity usage
Code
ENTITY* ent_global_example;
action Blupp(){
// wait (1);
// set bbox etc
   ent_global_example = me;
   while (my && level_loading) wait (1);
   while (my && !level_loading){
      ...
      wait (1);
   }
   safe_remove (me);
   ent_global_example = NULL;
}
action Bla(){
   while (my && level_loading) wait (1); 
 //while (!ent_global_example) wait (1); // we check for it in the while anyway...
   ...
   while (my && !level_loading){
      if (ent_global_example){
         ...
      }
      wait (1);
   }
   safe_remove (me);
}


I try to use event_frame whenever possible (but with sub ents i would prefer while's too i have to say because with event_frame you might end up with XYZ/Pan,Tilt,Roll that are one frame to old!).
Code below not tested but it should work:
Code
#define anm_frame      skill80
#define sub_ent_handle skill79

var level_loading = 0;

void event_testactor_wed(){
   if (event_type == EVENT_FRAME && my.sub_ent_handle){
      ENTITY* ent = ptr_for_handle (my.sub_ent_handle);
      if (ent && !level_loading && !freeze_mode){
         my.anm_frame += time_step;
         my.anm_frame %= 100;
         ent_animate (me, "idle", my.anm_frame, ANM_CYCLE);
				   
         vec_for_bone (ent.x,   my, "RightHand");
         ang_for_bone (ent.pan, my, "RightHand");
      }
      if (level_loading){
        my.event = NULL;
        if (ent) safe_remove (ent);
      //ent = NULL; // global pointers
        safe_remove (me);
      //return; // if more event code below!	
      }
   }		
}
action TestActor_WED(){
   while (my && level_loading) wait (1);
   ENTITY* ent = ent_create ("gun.mdl", vector (0,0,0), NULL);
   if (!ent){
      safe_remove (me);
      return;
   }
   else{
      my.sub_ent_handle = handle (ent);
      my.emask |= ENABLE_FRAME;
      my.event = event_testactor_wed;
   }
}
Or instead of ptr_for_handle its possible to use a global entity pointer, if the sub ent is only used by one entity.

Another way, maybe more clean with more actors
Code
#define anm_frame     skill80
#define right_handed  skill79

var level_loading = 0;

void attach_gun_to_actors (ENTITY* ent_actor, ent_gun){
   if (!ent_actor || !ent_gun) return;
   VECTOR tmp_pos;
   ANGLE  tmp_ang;
   if (ent_actor.right_handed){
      vec_for_bone (tmp_pos, ent_actor, "RightHand");
      ang_for_bone (tmp_ang, ent_actor, "RightHand");
   }
   else{
      vec_for_bone (tmp_pos, ent_actor, "LeftHand");
      ang_for_bone (tmp_ang, ent_actor, "LeftHand");
   }
   vec_set (ent_gun.x,   tmp_pos.x);
   vec_set (ent_gun.pan, tmp_ang.pan);
}

/* The "skill1-line" is no comment instead WED will show "RightHanded" in object properties instead of "Skill1" (reload wmp or main script to show) ;)
   Of course it makes no sense to use two skills for RightHanded...i just wanted to show this nice "hidden" WED feature here
   That’s why I always go from high skill #defines down to low ones, so that the first skills can be used in WED. */
//skill1 RightHanded 1
action Actor_WED(){
   while (my && level_loading) wait (1);
   my.right_handed = my.skill1;
   ENTITY* tmp_gun = ent_create ("gun.mdl", vector (0,0,0), NULL);
   if (!tmp_gun){ safe_remove (me); return; }
   while (my && !level_loading){
      my.anm_frame += time_step;
      my.anm_frame %= 100;
      ent_animate (me, "idle", my.anm_frame, ANM_CYCLE);
      attach_gun_to_actors (me, tmp_gun);
      wait (1);
   }
   if (tmp_gun) safe_remove (tmp_gun);
   safe_remove (me);
}


 ...

  level_loading = 1;
  wait (-1);
  level_load ("map2.wmb");
  wait (5);
  level_loading = 0;

 ...


While the "level_loading" stuff may be optional at first, it makes things so much safer and easier later on, especially when it comes to interactions between multiple global pointers.
Just wanted to say using stuff like "while(1)" with (global-) pointers can become dangerous very quick. I hope those example are "safe enough" for entity pointer usage and level switching.

It's a good idea to set
Code
fps_max = 60;
in your main function to keep
Code
time_step
constant!


Btw...I prefer a struct with entities, very clean, easy and good for many sub ents.

Greets
3 464 Read More
Shaders
09/27/26 13:52
Publish shock (again...)

I found out the hard way that the known "memory leak" is much worse then i thought...(23:00 to 8:00 with AI)


Only the published version will crash (without error message or acklog-entry) if you play for at least 5 minutes and reloading the level 5-10 times!
Edit: Note: if you play and respawn if you died, you can almost play for ever. It is the combination of "massive reloading" and "playing"! Never seen it crash without loading of any kind
First of all i hate that the published version of every Acknex project acts different in 1000 ways to the sed start, but sadly thats not new (no matter what warn_level etc).

I tryed everything...i did manage to call level_load only once(thought level_load itself is the problem in combination with shadec), building the map by script manually (yes, terror), managed the nexus by hand via
level_mark and level_free etc...still crashing. Nexus in this project atm 100-150mb max. So no "over 200" b*s*!

I guess the problem is deep in the shadec connection between Acknex and DirectX. Boh's "sc_reset" and "sc_destroy" functions
just dont work(!) if you call them once after you called sc_setup.

It seams not possible to end shadeC evo if it started once...because its engine-pointers are "async" to GPU for one frame.
I tryed to end it with new functions: it always ends in "invalid memory area" or "script crash in sc_forward_destroy / area_sc_reset ....".
It seems to be a fundamental problem with the connection between Shadec and DirectX. I'm just guessing.


The only possible way to use shadeC with massive "world reloading" / level switch seams to use a extern process (like my starter app) to control level switch from outside
of Acknex and hide the whole thing via a loading screen on the desktop.
The only way i see to really clear the "corpses" from shadeC in the GPU: end engine - restart engine in new level/with new content.
Without another process it could be done via exec and -nwnd option i guess...
Anyway...its a ugly hack!


3run did modify shadec evo once, i dont know if he came to the same results. Would be interesting what he modified exactly in his shadec evo verson back then.


Maybe im wrong, but i say ShadeC evo needs to be rewritten from scratch to get rid of this "destroy" problem.
I guess the mastermind Boh_Havoc did not test massive reloading/level switching in a published version. It seams like shadec was only tested like a techdemo in a
single WMB with not much happening around it (will run forever).
edit3: I was genuinely serious about "Mastermind"; I still take my hat off to the performance Boh_Havoc delivered here.

Just wanted to let you guys know.

edit2: Im pretty sure Dead Taste will show this behaviour too, when playing and clicking "new game" 5 times instead of clicking "Respawn" ...or how i called it back then.


If I'm talking nonsense here, I'm grateful to anyone who corrects me.
152 279,234 Read More
The Past
09/27/26 13:37
I still have the original A3 commercial version. I could offer the projects from the demo disk, if I can find the disks.
"Skaphander" comes to mind right away, i think that was the name.

Ah, those were the days....
[Linked Image]
50 30,144 Read More
Page 1 of 3 1 2 3

Gamestudio download | Zorro platform | shop | Data Protection Policy

oP group Germany GmbH | Birkenstr. 25-27 | 63549 Ronneburg / Germany | info (at) opgroup.de

Powered by UBB.threads™ PHP Forum Software 7.7.1