The Dink Network

Bah

January 22nd 2014, 03:55 PM
dragon.gif
Quiztis
Peasant He/Him Sweden bloop
Life? What's that? Can I download it?! 
Why is there a limit of 250 max variables and globals at a given screen? I guess there's no way to tweak this to get more space?

And things were going so well...
January 22nd 2014, 04:23 PM
wizardg.gif
leprochaun
Peasant He/Him Japan bloop
Responsible for making things not look like ass 
How many more do you need?
January 22nd 2014, 04:24 PM
dragon.gif
Quiztis
Peasant He/Him Sweden bloop
Life? What's that? Can I download it?! 
lots!

(probably hundreds more)

Dat "[ERROR] out of var space, all 250 used" shows up.
January 22nd 2014, 05:27 PM
custom_magicman.gif
magicman
Peasant They/Them Netherlands duck
Mmmm, pizza. 
Short answer: Nope. That limit is built into the engine.
Long answer: Oh, boy.

Do you have any unused screens? Write down their map number. Create an empty screen on one, and make it obvious that nobody should ever be there in-game.

Now what? Now you can make use of the editor_seq and editor_frame of the editor sprites on that screen! "But wait," you say "there are no sprites!". No worries. The engine doesn't really care, as far as I know.

Anyway, you basically just got 99 extra 8-bit unsigned variables (the editor_frames), and 99 extra 16-bit unsigned variables (the editor_seqs). And that per unused screen! Now how to use them? The following script demonstrates (just make sure that it's not attached to any sprite. That may be tricky):

void main( void )
{
  // Stuff here
  // Oh, crud, we need to store things but we ran out of globals.
  // Oh, well. Here goes nothing.
  // &mymap must be a global.
  &mymap = &player_map;
  // Replace 1 by the unused screen you want to use for this extra variable.
  &player_map = 1;
  load_screen();
  editor_seq(12,5);
  &player_map = &mymap;
  load_screen();
}


And retrieving the value? Same thing. Just put the editor_seq(12,-1); in a local variable, then jump back to the original screen:

void main( void )
{
  int &crap;
  // Stuff here
  // Oh, crud, we need to store things but we ran out of globals.
  // Oh, well. Here goes nothing.
  // &mymap must be a global.
  &mymap = &player_map;
  // Replace 1 by the unused screen you want to use for this extra variable.
  &player_map = 1;
  load_screen();
  &crap = editor_seq(12,-1);
  &player_map = &mymap;
  load_screen();
  say_stop("That value you stored six hours ago? &crap",1);
}


I think that should work. It works in a bit of code I'm writing right now, but at that point it's not running any other scripts at the same time. Not sure if already running scripts die when doing load_screen(), or as the first part of draw_screen(). It's even saved into the save game. You'll lose everything if you do a clear_editor_info(), so beware if you do the whole map.dat/dink.dat switching thing.

Anyway: load_screen() gives you access to a screen's editor sprites. They won't have any sp_* attributes, only editor_* attributes. It also won't make any scripts run, not even the screen base script. That all happens after draw_screen() which you should not use.
January 22nd 2014, 05:43 PM
dragon.gif
Quiztis
Peasant He/Him Sweden bloop
Life? What's that? Can I download it?! 
I'll look into this, thanks for pointing it out.
January 22nd 2014, 06:13 PM
eye.gif
synbi
Peasant He/Him Finland
 
I shudder to think what sort of a behemoth doomsday script you have going on there, and I'm curious. Huge explosions? Duck breeding simulator? Maybe a fully scripted DinkChess? Magicman's suggestion is genius though, it looks so insane that knowing how wonky DinkC is, it should probably work just fine.
January 22nd 2014, 06:44 PM
peasantm.gif
shevek
Peasant They/Them Netherlands
Never be afraid to ask, but don't demand an answer 
I tried this method before (actually I was getting the editor_* info of actual sprites on real screens, but that doesn't matter). But it causes a mess, unless you are in a very special situation. Which you are, but it should be special in the other way.

I don't remember exactly what the problem was, but I think it had to do with hardness. All sprite hardness disappeared, or the sprites wouldn't respect the hardness anymore, or something like that. All I want to say is be sure to test it thoroughly before spending a lot of time on it.
January 23rd 2014, 06:11 AM
wizardb.gif
Kyle
Peasant He/Him Belgium
 
It's nearly impossible to hit that cap, no matter hos complicated the script is. I know it's for the contest and you want to keep it secret, but in theory almost every script can be rewritten by only using 3 variables. Hence, I find it weird that you're hitting the cap. Let's say you create 100 sprites extra on the screen, you still only need one or two variables to create them and they are freed up again after. If your created sprites all need a variable, then they still won't need them at the same time. Look at the FIFO document in the dev files for more information.

In my d-mod I've hit instances of 40+ variables running concurrently and that's with new UI elements, a heavily modified spell/attack system and multiple enemies on screen. Add some lazy/sloppy coding to it here and there and I hit 40+.

Having said that, perhaps it really is something truly rare you're attempting and you need those variables... In that case, you're pretty much out of luck :/ You can attempt the editor_seq/frame trick for an exmpty screen (I fill them with scrolls of different colors to determine their use at a glance) and I haven't run into problems with it. The hardness shouldn't reset if you don't draw_hard_map anything. All it does is load the editor information of the screen after all, not change the current state of the screen for the player.
January 23rd 2014, 08:24 AM
dragon.gif
Quiztis
Peasant He/Him Sweden bloop
Life? What's that? Can I download it?! 
Dink Chess is a somewhat close one, synbi.

I have 80 squares on screen and each one messes with a number of different variables, like position of said square. A start script fills the screen with 80 50x50 large square sprites and attaches a script to each one. Right there it's a truckload of variables being used in each of those scripts.
All these squares has a global variable, &s1, &s2 etc. for various things.

Soo, yeeeaaahhh, didn't think of that 250 limit. I have to cut down on variables and be extremely resource efficient from now on.
January 23rd 2014, 09:37 AM
peasantm.gif
shevek
Peasant They/Them Netherlands
Never be afraid to ask, but don't demand an answer 
Ah yes I remember the problem. It wasn't related to getting editor_* values. The problem was that I used show_bmp ("...", 1); while player_map was on a different screen. That would mess with the background (which was to be expected) and hardness (which I didn't expect).

But this method gives us something we have been sorely missing: array variables. For an unused screen (or for any screen that doesn't use the editor_* values), we can use this as an array of globals, which can be indexed. It should make the chess thing a lot easier as well.

About hitting the limit, I've seen it too, even without using so many globals. The problem is that DinkC doesn't do garbage collection until it's done with executing scripts. I had a rather long nested loop to initialize a screen. This would hit the limit, because of all the locals that were kept around. Adding a few wait(1) statements solved the problem (and created others, which I solved by explicitly freezing Dink during the procedure).

Finally, if you don't need many bits per variable, you can store several of them in one actual global. It's not very comfortable to use, but it works. For example, to get and store a value in bits 4-6 of variable "storage", you can use:

int value = storage / 16 - (storage / 128 * 16);
say ("Value is &storage;, setting it to 2.", 1);
storage += 2 * 16 - value * 16;


(This is code which works in my preprocessor; I couldn't be bothered to make it real DinkC, if only because it would become unreadable. However, if you want to use it in a script without using my editor, I'm sure you'll be able to transform it yourself.)

This works because divisions are truncated to an integer, so a / 16 * 16 results in the value of a rounded down to the nearest multiple of 16. In fact, using this approach there's no reason to stick to powers of 2 (which makes it store things in bits); If you want to store a maximum of 3 numbers (0, 1 or 2) in a sub-variable you can just do a-a/3*3 to get the it (from the lowest bits).
January 23rd 2014, 10:09 AM
wizardb.gif
Kyle
Peasant He/Him Belgium
 
I have 80 squares on screen and each one messes with a number of different variables, like position of said square. A start script fills the screen with 80 50x50 large square sprites and attaches a script to each one. Right there it's a truckload of variables being used in each of those scripts.
All these squares has a global variable, &s1, &s2 etc. for various things.


You absolutely don't need all of that to make it function. Instead of storing the information of each square in variables, you should just store it in sprite properties like hitpoints, gold, defense, ... You won't be using those properties for their normal purpose anyway. So, in other words, you really only need one variable to store them away the first time. You also shouldn't identify the 80 squares as globals, that's way too many. Instead, give them a fake brain to track them.
January 23rd 2014, 10:31 AM
dragon.gif
Quiztis
Peasant He/Him Sweden bloop
Life? What's that? Can I download it?! 
Hm, I think I have a lot of things to try then, thanks.

If you come up with more ideas, post 'em!

EDIT: AAAAAAAAAANNNNNNDDddd I'm back on track! Wonderful!
January 23rd 2014, 01:34 PM
goblins.gif
you should just store it in sprite properties like hitpoints, gold, defense, ... You won't be using those properties for their normal purpose anyway

This is a great technique to keep in mind for any DMOD author. For example, say you want to make a chest that gives an exact amount of gold when you open it, but don't want to make a script for each chest. You can instead store the amount of gold the chest gives in it's sp_defense (which you can change in the sprite properties in the editor) in order to make chests that give all sorts of predetermined amounts of gold while using only 1 script to do it. The technique can be used for many other possibilities though, and definitely good to keep in mind at all times.
January 23rd 2014, 07:12 PM
peasantm.gif
shevek
Peasant They/Them Netherlands
Never be afraid to ask, but don't demand an answer 
You can instead store the amount of gold the chest gives in it's sp_defense

You could, but this would be the perfect thing to store in sp_gold, I would think. I would even suggest that that's what it was intended for, but of course with Seth you never know.

But I understood that other editors have no way to set sp_gold, right? They should fix that.
January 23rd 2014, 09:15 PM
dinkdead.gif
It also depends on how all your sprites use their scripts: if they're all running at once then you will have to do something tricky. If only one script runs at a time you can share global variables - the solitaire game I (half) made only uses 5 or so globals and each card has a fake brain to identify it like Kyle's suggestion.
January 24th 2014, 06:12 AM
wizardb.gif
Kyle
Peasant He/Him Belgium
 
If only one script runs at a time you can share global variables

There are no scripts that run at the same time, Dink does not support it. Hence, if there is no wait() in the scripts, you can safely rely on global variables anywhere you want
January 24th 2014, 09:24 AM
dinkdead.gif
Well, yeah, but I count that as "something tricky"

It's much easier when a script runs, finishes and then the next one runs later, rather than jumping between them all the time.