Data structures creating mods

Users who are viewing this thread

svaucher

Veteran
Just to make sure, we don't have access to datastructures when creating mod. By this I mean hashtables, stack or lists to do something like:

Code:
(assign, var("$quest[0]), $qst_abc)

Even if someone knows how to modify the name of a identifier, that would suffice. For example,
Code:
 (assign, "${mission}-{reg10}", 10)
.

If we don't, anyone know workarounds? I'm working on sending messengers to tell allied cities to attack another, but I land up having to use a bizarro way to simulate a queue of events. I thought of creating the configuration files dynamically, but I would basically scrap anyhope of being compatible with the next version of the modding system.

If I get no hints, I'll write up a some hacked data struts scripts and see if they can be useful for the community,

cheers,
sv
 
There is no structure support.

Variables are just an index into a list. So you can modify the variable index using any operator. The problem is reserving those indices for your use. You'd have to figure out how to do that (either by referencing fakes in some unused script or something else like modifying the python files to do it).
 
How can I access the index information? I set up my variables.txt to have
my 10 entry array (from index 0-9).

Let's call my vars entry0, entry1, ... , entry9

AFAIK, the for statement (try-for-range) will access the value of, and not the index of "$entry<n>". I assume that "$<varname>" means to access the variable with name <varname>, is there another way to access var information?

sv
 
If you look in the .txt files, there are no variable references. Only indexes prefixed with the index type. variables.txt is really only used by the unofficial editor, so that it can show the variable names being used in an operation.

When the python scripts run it creates a list of variables (which eventually get dumped to variables.txt). The index in the list is the actual value that is used in the script, plus the type is set in the upper 8 bits.

I haven't tried the following, and I have used the python scripts, so this may not work, but is an idea. Let's say you change the python scripts to support your entry[n] array (you can't just modify variables.txt for this). Then you may be able to access the 2nd element using something like:

( store_add, reg(1), "$entry0", 2 ),
( assign reg(2), reg(1) )

Now the second register contains the value in entry[2]. So if you wanted to access it in the try_for_range statement you'd have something like (assuming 10 elements):

( try_for_range, reg(1), 0, 9 ),
( store_add reg(2), "$entry0", reg(1) ),
( assign, reg(3), reg(1) ),
# now do something with the value
( end_try )

That might work...
 
Actually, I don't think that would work. I'm not sure how you'd get this to work with the python scripts. You'll probably need to add some methods to the python scripts to support this.
 
Effidian,

For your first post, I understand that the position of the variable in variables.txt is its id that is used internally. I cannot do pointer arithmetic with it therefore, I cannot modify the ref, only its value.

Any variation of
$foo = $foo + 1

will increment only the value of $foo.

For your example, it wouldn't work,

( try_for_range, reg(1), 0, 9 ),
( store_add reg(2), "$entry0", reg(1) ),
( assign, reg(3), reg(1) ),
# now do something with the value
( end_try )

This script would assign would do the following

reg(2) = $entry0 + 0 # first iteration
reg(2) = $entry0 + n # nth iteration
...
reg(2) = $entry0 + 9 # last

If I understood correctly, executing the python scripts output binary (config) files that are then parsed by M&B (probably in C++). I can modify the python scripts to generate the script config dynamically. instead of just parsing the 2 dimensional array, but I need to access its runtime values to perform lookups.

An example, is that I'm working on sending messengers in the game. I need to store the message (its currently a script), where to go (I use the ai_behaviour_object). Without datastructures, I'm limited to duplicate my variables and logic. For my currently config, I have 15 messengers, so 15 vars that hold the party ids, 15 vars that hold refs to scripts to execute when arriving at destination, 15 scripts to execute in case of death. I can automate the creation (in python) of these vars, but it's pretty ugly. I guess any solution will be a hack.

Thanks for the response (apologies for the long-winded response),
sv
 
Actually, after rereading what you said:

Effidian said:
The index in the list is the actual value that is used in the script, plus the type is set in the upper 8 bits.

Vars are 16 bits?
Does this mean that I could iterate over 2^16 values at startup and locate my array? Now that could be a great solution...

:shock:

It might be warped enough that it could work.

Effidian said:
you can't just modify variables.txt for this

I was prepending my array information to the variables using a python script.

sv
 
Hey svaucher,

Not sure if you've tried this already.

One option is to just do some good old-fashioned loop-unrolling whenever you see an array reference. This means you need to use your own loop construct that gets precompiled, not the (try_for_range) opcode that gets executed at runtime.

Example: We have an array of troop strings (called troopvar) that we're assigning into a bunch of registers.

This would appear in your module_blah.py:
Code:
(for_range, dummyvarname, 0, 5)
  (assign, reg(dummyvarname+10), "$troopvar_dummyvarname")
(end_for)

But what gets stored in blah.txt translates to this:
Code:
  (assign, reg(10), "$troopvar_0")
  (assign, reg(11), "$troopvar_1")
  (assign, reg(12), "$troopvar_2")
  (assign, reg(13), "$troopvar_3")
  (assign, reg(14), "$troopvar_4")

To do this you'd need to change ALL the process_blah.py to call a shared routine to precompile the new opcode (for_range) correctly.

Array indexing could be likewise replaced by a giant try statement:

Before:
Code:
(get_array_element, $troopvar, $index, $destvar)

Compiled to:
Code:
(begin_try)
(eq, "$destvar", 0)
(assign, $destvar, $troopvar_0)
(end_try)
(begin_try)
(eq, "$destvar", 1)
(assign, $destvar, $troopvar_1)
(end_try)
...

A bit messy, and probably horribly prone to error, but it will work.
 
svaucher said:
Vars are 16 bits?

They are 32 bits and the top 8 bits are used for the type. If you look at header_common.py and process_operations.py you'll see how that works.

Does this mean that I could iterate over 2^16 values at startup and locate my array? Now that could be a great solution...

I'm not following you here. If I get time, I'll mess around with this in the next couple days, but I imagine you'll have it figured out by then. :smile:
 
Effidian said:
They are 32 bits and the top 8 bits are used for the type. If you look at header_common.py and process_operations.py you'll see how that works.

Thanks for the reference. I could then use arrays, by creating my own scripts that would reserve mem slots (and maybe add syntax) to treat them as complex type. Don't know if it would be valuable for others. I'll put that project on the backburner until I finish my next addition to my mod.

Effidian said:
svaucher said:
Does this mean that I could iterate over 2^16 values at startup and locate my array? Now that could be a great solution...
I'm not following you here. If I get time, I'll mess around with this in the next couple days, but I imagine you'll have it figured out by then. :smile:

Warped sense of humour on my part. I'm very much a geek,

thanks for your responses,
sv
 
fisheye said:
A bit messy, and probably horribly prone to error, but it will work.

Yup, very error-prone. Especially considering, the intuitive else_try statements don't work as advertised (hey it's still beta).

I'm faced with the Pareto Principle, for 80% of work, I'll get 20% of what I need... As a programmer, I'm used to being able to organise my data in a neat way. What I would *love* is to be able to do this kind of thing without it becoming something that no one will ever understand. If I'm really stuck at some point, I'll add structs which will be as you sais precompiled into the static format readable by M&B. For now, I'll keep on having fun trying to do some perverted stuff :wink:

sv
 
Back
Top Bottom