In Progress Double Dragon Mini

The project is currently under development.
In my case, I had to work around a limitation of the OpenBOR engine: it does not support arrays in scripts. So for the 10×20 playfield, I used individual global variables for each cell:

Oh no, friend, you should have asked first. OpenBOR very much does support arrays. It has indexed arrays, and literal key arrays, the later with a native cursor for traversal.

Both types support nesting for building multi-dimensional arrays. You can even nest different array types into each other.

Your workaround, while commendable, is specifically one of the things we try to warn creators to never do.

Here's a tutorial I wrote if you're interested. There's a copy here in the forum too, but this one is newer.


Next time throw us a line if you're unsure about something. Any time you have decided there's a limit to the engine, I can almost guarantee you it has a solution specifically tailored to handle your problem. :)

DC
 
I have a problem, or maybe I'm misunderstanding something. The standard HitFX function behaves strangely. When I put HitFX in an attack animation, the sound gets distorted — you can hear it in some of the videos I've posted. Sometimes the sound plays fine. OpenBOR v. 4

Sound it's one "Tube_hitfx.wav" but playing different in 00:52:00 и 00:54:00

In 00:54:00 sound right
In 00:52:00 sound different

It’s the same with many animations — sometimes they play fine, sometimes they get distorted.

HitFx natively tunes playback speed to distort the sound based on damage output. It's hardcoded to assume 10 as baseline damage.

Best advice for hitfx is don't use it. It is an archaic functionality from the original BOR left in for backward compatability. To add hit sounds, use flashes instead - an invisible one if you don't need visual effect, and play sounds from the flash model. You will find this is much more elegant to work with.

HTH,
DC
 
Oh no, friend, you should have asked first. OpenBOR very much does support arrays. It has indexed arrays, and literal key arrays, the later with a native cursor for traversal.

Both types support nesting for building multi-dimensional arrays. You can even nest different array types into each other.

Your workaround, while commendable, is specifically one of the things we try to warn creators to never do.

Here's a tutorial I wrote if you're interested. There's a copy here in the forum too, but this one is newer.


Next time throw us a line if you're unsure about something. Any time you have decided there's a limit to the engine, I can almost guarantee you it has a solution specifically tailored to handle your problem. :)

DC
Thank you so much for the clarification! I really got myself into a pickle — all that struggle with generating variable names, and it turns out there were proper arrays with indices and lists available all along. I admit that was an oversight on my part: I should have asked right away instead of building workarounds.😯

The guide you wrote is a real gem. The section about hash acceleration for string keys was especially useful: now I understand why dynamic variable names hit performance so hard. I'll gladly study the whole thing.

I'm currently rewriting the mini-games to use indexed arrays. Tetris has already been converted to a 200-element field array — the code became much cleaner and faster. Next up are Galaga, Breakout, and Snake.

Thanks again for the support and for sharing your knowledge. Next time I have doubts, I'll check the documentation or ask on the forum first.(y)
 
HitFx natively tunes playback speed to distort the sound based on damage output. It's hardcoded to assume 10 as baseline damage.

Best advice for hitfx is don't use it. It is an archaic functionality from the original BOR left in for backward compatability. To add hit sounds, use flashes instead - an invisible one if you don't need visual effect, and play sounds from the flash model. You will find this is much more elegant to work with.

HTH,
DC
Thanks for the explanation! That makes perfect sense now — the distortion was actually tied to the damage scaling, which I didn't realize. I had a feeling HitFX was doing something weird under the hood.

I'll definitely switch over to using flash entities for hit sounds and remove HitFX from my attack animations. The invisible flash approach sounds like a much cleaner and more flexible solution.

Appreciate you clearing that up!;)
 
Thanks for the explanation! That makes perfect sense now — the distortion was actually tied to the damage scaling, which I didn't realize. I had a feeling HitFX was doing something weird under the hood.
you set this to prevent the speed change:

noslowfx {bi}

  • If set to 1, hit sounds will always play at the normal speed. Normally, the higher the damage of an attack, the slower it's hitsound plays.
 
you set this to prevent the speed change:

noslowfx {bi}

  • If set to 1, hit sounds will always play at the normal speed. Normally, the higher the damage of an attack, the slower it's hitsound plays.
Hmm... Wow, it turns out the solution was right under my nose, haha. 😄 Thank you so much, you helped me a lot! Still, I’m going to stick with the default HitFX function. Making custom HitFX for Flash with all my different sounds would mean creating too many different Flashes, and that might get confusing.
 
Refactoring Double Dragon Mini: moving to OpenBOR arrays

Hi everyone! ;) I'd like to share some optimization work I did on our project Double Dragon Mini. For a long time the code relied on dynamically generated global variable names:

C:
setglobalvar("tetris_cell_" + col + "_" + row, value);
setglobalvar("galaga_enemy_alive_" + i, 1);
It worked, but every access involved number-to-string conversion, concatenation, hashing, and hash-table lookup. In hot paths (dozens of calls per frame), the overhead added up quickly. 😵‍💫

What I changed

After reading Damon Caskey's guide "Using OpenBOR Arrays", I moved all homogenous data to indexed arrays (array(N)), which give O(1) access through simple offset arithmetic.

Mini-games (8 total):
  • Galaga — 10 arrays of 5 elements each, replacing 50 global variables
  • Breakout — one array of 18 bricks
  • Snake — segment coordinate arrays (200 elements, plenty of headroom)
  • Dodge — 4 arrays of 5 objects each
  • Tetris — playfield array of 200 elements
  • Pong, Flappy Bird, Whack-a-Mole — small data sets, left as-is
Main menu:
  • 14 cheat codes (~560 lines across 28 blocks) compressed into 3 array-based functions (~150 lines). A single call to process_cheat_codes() replaces all the input parsing.
  • Gallery: 16 variables → 2 arrays, gallery_arts[8], gallery_cache[8]
  • BVD Team: 4 variables → 1 array
Gameplay update:
  • Move List previews: 22 variables → 3 arrays
  • Options coordinates: 15 variables → 1 array opt_coords[15]
Memory management

Following the guide's recommendations:
  • Pointer validation before use: typeof(arr) == openborconstant("VT_PTR")
  • After free() always setglobalvar("...", NULL())
  • Arrays are allocated once and never resized in hot paths
  • No add() or delete() inside the gameplay loop — only get() and set()
Results
  • Performance: hundreds of string concatenations and hash lookups per frame eliminated
  • Readability: menu_script.c shrank by roughly 400 lines
  • Reliability: unified cleanup pattern removes memory leak risk
Big thanks to Damon Caskey DCurrent
for the detailed guide — without it I'd still be building workarounds. If you haven't read it yet, I highly recommend it: Using OpenBOR Arrays 😁
 
Back
Top Bottom