Heroes of Might and Magic Community
visiting hero! Register | Today's Posts | Games | Search! | FAQ/Rules | AvatarList | MemberList | Profile


Age of Heroes Headlines:  
5 Oct 2016: Heroes VII development comes to an end.. - read more
6 Aug 2016: Troubled Heroes VII Expansion Release - read more
26 Apr 2016: Heroes VII XPack - Trial by Fire - Coming out in June! - read more
17 Apr 2016: Global Alternative Creatures MOD for H7 after 1.8 Patch! - read more
7 Mar 2016: Romero launches a Piano Sonata Album Kickstarter! - read more
19 Feb 2016: Heroes 5.5 RC6, Heroes VII patch 1.7 are out! - read more
13 Jan 2016: Horn of the Abyss 1.4 Available for Download! - read more
17 Dec 2015: Heroes 5.5 update, 1.6 out for H7 - read more
23 Nov 2015: H7 1.4 & 1.5 patches Released - read more
31 Oct 2015: First H7 patches are out, End of DoC development - read more
5 Oct 2016: Heroes VII development comes to an end.. - read more
[X] Remove Ads
LOGIN:     Username:     Password:         [ Register ]
HOMM1: info forum | HOMM2: info forum | HOMM3: info mods forum | HOMM4: info CTG forum | HOMM5: info mods forum | MMH6: wiki forum | MMH7: wiki forum
Heroes Community > Heroes 3.5 - WoG and Beyond > Thread: ERM help and discussion
Thread: ERM help and discussion This Popular Thread is 407 pages long: 1 2 3 4 5 ... 80 160 240 320 400 ... 403 404 405 406 407 · «PREV / NEXT»
Cybernetic
Cybernetic


Known Hero
Cypriot Legend
posted June 02, 2003 08:33 AM

Quote:
yeah, thats what the Wogify Options menu is for.


Exactly......"Look on the bright side of life...."
____________

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Gangrail
Gangrail


Promising
Famous Hero
Dead Man
posted June 09, 2003 07:22 AM

Town Demolition useless?  You ever hit enemy town and destroy its creature dwellings and then continue on your way?  It is very nice to do if you have an enemy with more than 1 town.  You simply move in destroy it's dwellings and leave to continue your attack on his land.  No longer the need to worry about defending the town from him while trying to destroy his others.  And if you have the time to waste you can destroy it completely and it is useless for 7 days.
____________

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Vlaad
Vlaad


Admirable
Legendary Hero
ghost of the past
posted June 09, 2003 09:09 AM

I agree! I grew to like the "scorched earth" tactics playing Age of Wonders. I know it's not the same in WoG, but it sure helps, as explained above.
____________

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Cybernetic
Cybernetic


Known Hero
Cypriot Legend
posted June 10, 2003 05:49 AM

It might not be useless, but way to expensive and time consuming, if it didn't take so long to demolition everything expectly if the castle built everything
____________

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
zvs
zvs


Hired Hero
posted June 10, 2003 01:29 PM

 Hello, Community!

 I am Slava, if you need me.
 I am busy enough and cannot spend much time in forums. I do not remember when I was here the last time. Fortunately I see that WoG team representatives are really active here (Gangrail, Kitten, Fnord, somebody else?). But now that I visit this friendly place and see such a big activity here (I think more than at our offocial forum on Celestial Heavens), I will difinitely come here more often.
 Promise :-)

IRh:
*******
Why do talented and creative people have lack of knowledge? Why are brilliant and needed ideas realized so?
*******
 Well... I could speak about this, but only few things you should know/check/answer before continuing:
- I have a PhD degree in Computer Science;
- I wrote a couple of compilers (check H4Util and "C-like" scripting language that is realized there);
- do you know that ERM meets the Object Oriented theory requariments?
- do you know that ERM grew up from Stand Alone ERM addon?
- have you ever tried to add the code for already compiled program (EXE file)?
- have you wrote your translator or you need help?
 And finally, ask me why first, then try to speculate, Ok?

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
IRh
IRh


Famous Hero
Lizard
posted June 10, 2003 04:13 PM

* My e-letter to ZVS, roughly translated: *
Well.
1st, sorry for flame. I understand, when a lamer in his first posts begins to pour evereything with s*, it is ugly. (BTW, it's my first forum).
I was in rage.

> IRh:
> *******
> > Why do talented and creative people have lack of knowledge?
> > Why are brilliant and needed ideas realized so?
> *******
> Well... I could speak about this, but only few things you should know/check/answer before continuing:
> - I have a PhD degree in Computer Science;
> - I wrote a couple of compilers (check H4Util and "C-like" scripting language that is realized there);
Sorry, I haven't know. *downloading* Yes, good language.
My error. I thougth you cannot write translators.
> - do you know that ERM meets the Object Oriented theory requariments?
joke? .
seriously: Yes, I don't know this reqs, believing ERM meets them formally. But what? IMHO, the main problem is that ERM doesn't meet the modern language requirements.
> - do you know that ERM grew up from Stand Alone ERM addon?
I've heard smth. And what?
> - have you ever tried to add the code for already compiled program (EXE file)?
No. And I even don't know how. Supposing it's not simple. Hard work you did. I say nothing about it.
Or it intersects with a language part?

> - have you wrote your translator or you need help?
The script I compiled yesterday:
on enter to EYE_OF_MAGI:
{
if (this_hero.attack > 1)
give to this_hero this_hero.power * 5 RUST_DRAGONS;
}

It's not all. I think it would be smth like  Ñ and SQL or 4GL.
I was near to begin discussing this project.

> And finally, ask me why first, then try to speculate, Ok?
* searching for 'speculate' *
Yes, you're right. Can I ask what were the problems?


____________

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
2XtremeTotake
2XtremeTotake


Promising
Supreme Hero
posted June 18, 2003 04:06 PM

i would like to create a Cyclops lord, more powerful than the Cyclops and Cyclops king, and it attacks wiht 100% precision on castle walls, meaning it always hits the exact target.....I also want to give him a mullet since Cyclops have  Ponytails...i want ot give the cyclops lord a mullet, now if someone would tell me HOW to do it.....it doesnt require photoshop does it...?
____________
I almost had a psychic girlfriend but she left me before we met.

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
alf
alf

Tavern Dweller
posted July 31, 2003 11:30 AM

ERM

I also just started to look at ERM and I must admit that I tend to agree with Irh to some extent.

I do believe that ERM itself might be under various constraints. For one thing I am puzzled why it isn't using a stack machine model for its running. Stack machines are a time honored and very efficient model which can support object orientation and other high level stuff while still be efficient. It is used by postscript, Java, Javascript, .NET engines and many others. I assume that the reason why ERM isn't using a stack machine model is due to constraints in working with the original heroes executable.

That does not prevent us from writing a high level language compiler which can take more readable input and translate it to ERM though although I would believe the best solution would be to have the ERM engine be stack based - however, if that doesn't work we have to do the next best thing.

For this purpose I am playing around with the idea of specifying a language which can be used for input with ERM as output. The idea is that you compile your script and the output is an ERM file which you can then paste into the event text in the game.

Would there be any interest in such a tool or would Irh and I be the only people interested in it?

I thinking of something along the following lines:

The input file is a sequence of declarations followed by a sequence of triggers.

receivers are defined within the context of a trigger and are therefore not present in the outer level.

instructions are simply receivers which respohnd to a "loading map" trigger and shouldn't really be separate thingies.

However, before the triggers I want the user to be able to declare symbolic names for things related the script. Possible declarations would be:

bool IDENT use FLAG;

Here uppercase letters are meta symbols while lowercase are taken literally. The IDENT is some identifier which identifies a boolean flag, FLAG identifies which flag variable to associate with IDENT.

For example if you have a flag 147 with the intended meaning that it is set whenever a specific town named Capitol is captured and it is not set before this then you can decalre:

bool CapitolCaptured use 147;

Later on you can then use CapitolCaptured in the script and the compiler will translate it to flag 147.

Another declaration is a string declaration.

string IDENT use STRINGVAR;

for example:

string UserInput use 132;

This will resolve in the variable UserInput referring to variable z132. The z is implied but you should probably be allowed to spell it out as well so "use z132;" should work as well.

Another declaration would be

int IDENT use INTVAR;

As above INTVAR identifies the variable, if the variable is a w-variable it is per hero. Hero variables can also be defined by:

int IDENT use hero HEROVAR;

HEROVAR can be w130 meaning hero variable w130 or it can be a plain number 147 which means variable w147.

The above associate symbolic names to variables so you can use those names instead of variable numbers in the following code.

Some variables are used by the system and those variables have predefined names which are available even if you don't declare them - and you can't declare them as their names are reserved words. Exactly what those words are I don't know yet

Other declarations can associate symbolc names to heroes, items and cities.

hero IDENT use HERO;

IDENT is again an identifier while HERO identifies some specific hero - either a number or a name. If the name contain spaces or quote characters etc the name must be quoted in double quotes. Later in script when a reference to a hero is made you can either use HERO or IDENT to refer to the hero or if the hero is the current hero related to the trigger or some such you can use other pseudo names referring to 'current hero' or 'the other hero' if in an encounter etc.

item IDENT use ITEM;

like heroes, you can use the item's official name or a number. new items must be defined by numbers.

Similarly for creatures

monster IDENT use MONSTER;

MONSTER is either a number or a monster name. If the name contain spaces or other special characters it must be in double quotes. To get the upraded version you can use the word upgrade' in front of the monster name.

for example:

monster giants use upgrade titans;

When the script later on use the word 'giants' the script translates this to the upgraded version of titans.

Instead of a monster name or number you can use a city type followed by a level. For example:

monster giants use tower upgrade level 6;

In addition you can also define a player list. Some things require a set of players and it might be a good idea to define a team once and for all at the top of the script and use that symbolic name instead of enumerating the same colors each time.

team IDENT use LIST-OF-COLORS;

for example:

team niceguys use red, green, tan;
team baddies use teal, pink, green, orange, purple;

The last one is everyone except the niceguys so you could have written:

team baddies use not niceguys;

instead with the same effect. The special name 'everybody' refer to the list of all colors and the name 'nobody' refer to an empty team of no members, this is normally not useful but can be used to initialize a variable with a team and then add in members from a dialogbox or whatever.

There might be more declarations as we see them fit but this should cover the majority I think.

Note, the declarations do not produce any ERM code. They are information to the compiler only and builds up translation tables. In particular the ERM code will never contain any references to the declared identifiers.

After the declarations a list of triggers follows. I believe it is cleanest to have a 'map loading' trigger or 'map start' trigger than "instructions". In other words you declare a trigger with the name mapstart or some such and the body of that trigger (the 'receivers' inside) are not receivers at all but are instructions. This will place all instructions in one part of the ERM and not mix it with receivers. What do you experienced ERM writers think about that? Is it necessary to allow instructions to come anywhere in the ERM script? I would believe it is never necessary to mix them since the instructions are always executed early on anyway long before any of the other things in the script. For this reason I therefore think that having instructions as a separate entity in the high level code is a bad idea and we just make a special trigger for them.

trigger mapstart { ..... }

The stuff in .... are instructions, i.e. they generate !# ERM code.

All the other triggers have a more or less one-to-one correspondence with the ERM triggers, for example:

trigger battlestart { .... }

if you want conditional triggers you use a WHERE clause:

trigger battlestart where BOOLEXPR { .... }

The trigger will only be in effect if BOOLEXPR is true, for example

!?BA0&1/-2/3;

will be written as

trigger battlestart where A && !B && C { .... }

where A is defined by "bool A use 1;" etc.

The instructions inside the .... are receivers that are placed after the trigger.

Some triggers take parameters, for example:

trigger location(X,Y,Z) { ... }

Here X, Y and Z are parameters to the location.

The rest is all receivers and instructions and they form the "executable" code inside the body of the triggers.

One point may be concerning the FU triggers which really aren't triggers at all but rather a way to declare functions. They should probably be defined as functions instead:

function IDENT use FUNC { .... }

Here FUNC is a number or some such that identifies the function in ERM while IDENT is our own symbolic name for the function.

About the receivers they should use regular C-style expressioons as much as possible. For example to increase a hero identified in variable H's power by 3 use:

H.power += 3;

The compiler will translate this to a sequence of ERM commands to perform this task. Note the compiler should also optimize to some extend if you both do:

H.power += 3;
H.attack -= 2;

It should be combined into a single ERM command to adjust both stats whenever the compiler see that is possible to do.

Similarly, hero variables are always relative a specific hero, so if you have defined D as a hero variable (w120 for example) then you can use H.D = 7; to assign it to 7. Again, the compiler should keep track of current hero and never issue a "set current hero" unless the variable H refer to some other hero or the variable H may have changed since last time. I would assume some complicated analysis would be needed for this and this is probably the most complex part of the compiler and would likely cause most of the work.

Is there any interest in a compiler such as the above?

Alf

____________

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
fnord
fnord


Promising
Famous Hero
posted July 31, 2003 11:08 PM

Quote:
That does not prevent us from writing a high level language compiler which can take more readable input and translate it to ERM though although I would believe the best solution would be to have the ERM engine be stack based - however, if that doesn't work we have to do the next best thing.

For this purpose I am playing around with the idea of specifying a language which can be used for input with ERM as output. The idea is that you compile your script and the output is an ERM file which you can then paste into the event text in the game.

Would there be any interest in such a tool or would Irh and I be the only people interested in it?



I don't know too much about the technical aspects of ERM and the reasons Slava wrote ERM the way he did, but for me, I'm used to it now and fairly comfortable with its syntax, so I probably wouldn't bother with a compiler that used more natural language.

Your ideas are interesting, however, and I expect that if you get some feedback, you can judge better if there's enough interest in the community to make it worth doing.

One note: you may or may not have looked at the Macro commands, but they do provide a way of using names instead of variables, similar to some of the things you describe. ERM macros must all be enclosed in $ signs, but otherwise, they would work for some things the way you're suggesting for constants or other predefined variables.


____________

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Alf
Alf

Tavern Dweller
posted August 01, 2003 12:27 PM

Quote:

I don't know too much about the technical aspects of ERM and the reasons Slava wrote ERM the way he did, but for me, I'm used to it now and fairly comfortable with its syntax, so I probably wouldn't bother with a compiler that used more natural language.

Your ideas are interesting, however, and I expect that if you get some feedback, you can judge better if there's enough interest in the community to make it worth doing.

One note: you may or may not have looked at the Macro commands, but they do provide a way of using names instead of variables, similar to some of the things you describe. ERM macros must all be enclosed in $ signs, but otherwise, they would work for some things the way you're suggesting for constants or other predefined variables.




I just wrote an E-mail to Slava and asked him a couple of questions. After looking into the topic I also realize that there are some obstacles in the form of optimization:

Problem is this: Let's say you have one ERM command. These ERM commands typically do several things in one statement, for example the command to change a hero's primary stats can change all of them and will do so unless you speciay 'd0' or some such in their place. In a high level language these would typically be several statements and so you must have a way of detecting and combining multiple statements into one ERM command - of course, the converse is also true in that one high level statement may produce several ERM commands.

This can get quite hairy, especially if you have a variable which may change so if you set:

var.power = 13;

and then later on do:

var.knowledge = 14;

does that mean you can combine them? Well, yes if var has the same value in both statements but not if the value of var has changed in between.

It's not impossible to make a compiler that can track such things and produce reasonable good code but it might require  too much work and even then it wouldn't beat a good ERM programmer - at best it would be "just as good".

I'm not saying it's impossible to do but I do have second thoughts about if it is worthwhile and so I absolutely would like to get more comments from people like Fnord who has written several ERM scripts and who are experienced in it. I would also like to get response from Slava but he didn't respond yet - gotta give him some time

I appreciate your comment Fnord, just hope that more people will respond.

Alf

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Gangrail
Gangrail


Promising
Famous Hero
Dead Man
posted August 01, 2003 06:51 PM

You won't get a response from Slava for about 10 days he is on vacaction.  He might be able to get to his email but not sure.  So if you get no response for 2 weeks that is why.
____________

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
IRh
IRh


Famous Hero
Lizard
posted August 11, 2003 06:23 PM

Hi Alf...
Interesting notes. You seem to be the only (except Slava)  person to accord with me.
A compiler would be a good idea... I think about it, but with some private problems and I don't know...
Your ideas have something in common with mine ones. What I think about:

bool EyeVisited = TRUE, f;

initially:
{
 // disable standart action
 disable EYE_OF_MAGI;
 f = TRUE;
}

on enter to EYE_OF_MAGI when f:
{
 if (!EyeVisited)
 {
   say "Hello";
   this_hero.power += (this_hero.knowledge + 45) / 2;
   EyeVisited = TRUE;
 }
 else
   say "**** off";
}


I don't think user needs to mess with variable number, compiler does. I thought about it and I have several ideas, this later.

Some of your thoughts are familiar with things I thought about in the beginning, but later I understood they're wrong. What I meant: we can, for example, write:
monster giants use tower upgrade level 6;
set mine(144, 144, 1) resource to GOLD;

but how shall we get these values? Like that?:
get mine(144, 144, 1) resource into <variable>;
I think we'll have to use field syntax:
// Only for example
mine(144, 144, 1).resource = mine(5, 6, 0).resource + 1;
GIANTS.upgrade = STYG.slot(0); // monster in 0 slot of Styg's army

One of my severe errors (me stupid, shame 8[) is that I began planning a language before looking though the full recievers list. Alf, maybe you forgot, too? I thought there must be only 'hero' and 'monster' classes with fields syntax; now I've found it needs a lot of them. Only class types:

battle
action
mouse
int
hero
side
town_event
event
monsters // creatures
wandering
player
point
art
town
event // local_event ?
monster
object
mine
scholar
chest
tomb
tree
campfire
lean_to
learning_stone
<...>
dwelling
shipyard
garrison
shrine
univercity
sign
square // point

And every type has several fields; some of them being with parameters (ASMODEUS.monster(i) = this_hero.monster(i)). Hard. Needs an idea. Thinking.

Yes, as you said the output code won't be so compact as human's. Compare:
!!HE-1:S3/5/d0/d0; [human]

and
!!HE-1:N?y1; [estimated compiler output for current version]
!!VRy2:S3;
!!HEy1:Sy2/d0/d0/d0;
!!HE-1:N?y1; [again? : (  ]
!!VRy2:S5;
!!HEy1:Sd0/y2/d0/d0;


Even after certain optimisations the code would be 2-5 times larger and correspondingly slower; it is bad for long loops, 4X WoGify scripts. But not fatal, is it?
And, a HLL programmer will surely beat ERM-er in quality and quantity of scripts, also the pleasure of writing. Seriously, wasn't that Stroustrup to say that language programming must be pleasant?


P.S. About stack languages: I don't think they're good. With some practice, you can write programs keeping your eyes closed, but you cannot read them. The best way to fix an error is to delete an expression and retype it. How can you guess that this 'x' is applied to tha-a-at function f without looking the whole stack operation chain? I've small experience in PostScript. What's good in 'x y z * +' notation?..
P.P.S. A question to Alf: You are a programmer, am I right? Have you some experience in this area? Not depending of the answer, your ideas are interesting. please post.
____________

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
zvs
zvs


Hired Hero
posted August 14, 2003 10:34 AM

****************
Even after certain optimisations the code would be 2-5 times larger and correspondingly slower; it is bad for long loops, 4X WoGify scripts. But not fatal, is it?
****************
 Do not think about optimization now. First make a straight transtalor. All optimization may be shelved (if it is needed at all). ERM itself works very fast and size is not important if it is an external script (timed events on a map are limited to 32k of text).
 So go ahead, make it somehow.

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
IRh
IRh


Famous Hero
Lizard
posted August 20, 2003 04:39 PM

Damn I hope so. Before Heroes will be used only by nostalgiating 70-years men on emulators... 8[
____________

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Garrett
Garrett

Tavern Dweller
posted August 20, 2003 06:57 PM

This is pretty serious.
Some time ago, a line of ERM script remained in my map somehow, I noticed that because I kept getting ERM Syntax Errors even though everything was perfect, then I found something, I saved my script with the same name as the map and in the same folder (maps), I moved the folder and everything went back to normal...Until now, the same thing is happening, but this time there aren't any files that might be interfering, will CopyMap fix it? And if so, how am I supposed to use it?
Yelp.
____________

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Gangrail
Gangrail


Promising
Famous Hero
Dead Man
posted August 22, 2003 05:26 PM

Is there any chance there is a line of erm in the map event itself?  If there is a timed event in your map that has erm in it it will never leave until you remove the event.  Just asking incase you overlooked this.  Because I have not fooled with erm much but have never known erm to work by just having it named the same as the map and be in the map dir.  For erm to be automatically active it has to have a specific name and be in the data\s dir.  And erm never adds itself to a map in any shape or form.  I can only think that the map has a timed event starting with ZVS in the text protion of the event.  If this is not the problem please send me the map to see what is happening myself.
____________

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Garrett
Garrett

Tavern Dweller
posted August 22, 2003 08:44 PM

It's too late I'm afraid, I copied all map data with CopyMap and deleted the original, everything is back to normal now. Thanks anyway.
____________

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Alf
Alf

Tavern Dweller
posted August 25, 2003 08:19 PM

Km@Km@i Alf...
Interesting notes. You seem to be the only (except Slava)  person to accord with me.
A compiler would be a good idea... I think about it, but with some private problems and I don't know...
Your ideas have something in common with mine ones. What I think about:

bool EyeVisited = TRUE, f;


What is that 'f' doing there, another bool var?
Quote:

initially:
{
 // disable standart action
 disable EYE_OF_MAGI;
 f = TRUE;
}

on enter to EYE_OF_MAGI when f:
{
 if (!EyeVisited)
 {
   say "Hello";
   this_hero.power += (this_hero.knowledge + 45) / 2;
   EyeVisited = TRUE;
 }
 else
   say "**** off";
}


I don't think user needs to mess with variable number, compiler does. I thought about it and I have several ideas, this later.


Agree with that in principle, however, if you want to mix HLL and ERM you will invariable want to control which variable ends up where...
Quote:

Some of your thoughts are familiar with things I thought about in the beginning, but later I understood they're wrong. What I meant: we can... etc...


Well, I too agree on a field style syntax for it but I don't know exactly how many different object types you need and that might also possibly change if the ERM language continue to evolve.

Also, several of the object types you mention do not have to be separate object types as long as we say an object has certain standard fields as long as those fields apply to that object we don't really have to provide syntax to define various object. For example for the map objects (lean_to, etc) it is enough to know that they are "objects" as far as the language goes without actually having to know exactly which object each is.

So you might end up with having some special objects but mostly all objects are such that as far as the syntax of the language goes, any object can have any field. Only certain
objects need to be typed so that the compiler knows exactly what type of object it is. For the remaining objects the type is simply an attribute of the object which can be checked at compile time and as long as it matches the fields you can use those fields but without having a rigorous declaration system for each object such as a lean_to which only hold resources much the same way a camp fire does - for the language we don't need to care then if the object is a camp fire or a lean_to unless you want to do something which affects all lean_to objects but not camp fires.
Quote:

And every type has several fields; some of them being with parameters (ASMODEUS.monster(i) = this_hero.monster(i)). Hard. Needs an idea. Thinking.


This can mostly be solved by simply having "army" as an object type which can hold a collection of monsters. It is a chopped down version of "hero" since it has stacks of monsters but without any hero to lead them.
Quote:

Yes, as you said the output code won't be so compact as human's. Compare:
!!HE-1:S3/5/d0/d0; [human]

and
!!HE-1:N?y1; [estimated compiler output for current version]
!!VRy2:S3;
!!HEy1:Sy2/d0/d0/d0;
!!HE-1:N?y1; [again? : (  ]
!!VRy2:S5;
!!HEy1:Sd0/y2/d0/d0;


Even after certain optimisations the code would be 2-5 times larger and correspondingly slower; it is bad for long loops, 4X WoGify scripts. But not fatal, is it?


I read zvs' response further below. It seems like the optimization shouldn't be such a worry so we can just go ahead then?
Quote:

And, a HLL programmer will surely beat ERM-er in quality and quantity of scripts, also the pleasure of writing.


definitely.
Quote:

P.S. About stack languages: I don't think they're good. With some practice, you can write programs keeping your eyes closed, but you cannot read them. The best way to fix an error is to delete an expression and retype it. How can you guess that this 'x' is applied to tha-a-at function f without looking the whole stack operation chain? I've small experience in PostScript. What's good in 'x y z * +' notation?..


The stack language isn't supposed to be humanly readable either, they're usually assembly like thingies. The point is that it is relatively easy to make a compiler that read HLL on input and produce stack language on output and executing a stack language can be very fast. The real charm of stack language is that it is very flexible. You don't need a huge vector of variables and flags etc. For example you can have a vector for global variables G[0] to G[some_max] and then you have the stack S[0] to S[some_other_max} or it can be dynamic and grow as needed. The idea is that all events etc would then simply push whatever relevant values related to the event on the stack, so you didn't have to reserve for example number 998, 999 and 1000 for one meaning and then not being able to get that other value because you don't have any register to store that value etc. If an event can provide 20 values relevant to the event then you push 20 values on the stack and the event handler have them available. For example in a event that hero A meets hero B at location X, Y, Z I can immediately think of 5 values which is nice to receive in the event handler for that event, the hero indices and the 3 coordinate values. Sure you can define that the hero index goes in some special global variable G[29] or whatever and possibly it would be good to place it in a special variable so you can use a simple value such as -1 or some such to mean "current hero" but this event have two heroes that interact, the "current hero" and the hero he or she meets. A stack is such that you just push those values on the stack in some pre-defined order and the event handler or receiver for the event must then pick up the values in that order (actually opposite order since that is how a stack works). So a receiver can
have 0, 1, 5 or 20 arguments or values, the framework doesn't care.
Quote:

P.P.S. A question to Alf: You are a programmer, am I right?


right

Quote:

Have you some experience in this area? Not depending of the answer, your ideas are interesting. please post.

If you mean experience in the area of stack based languages etc, yes. I have both used them and programed (created) such engines.

For example I once made a byte oriented stack based code where some instructions were only one byte and some were two bytes and apart from immediate arguments no instruction was more than two bytes.

For example the instruction to push 5 on the stack was simply the number 5 So values 1-63 was all such "push self on stack" and it also had some "registers" or global values if you like and you could load and store values from stack to the registers. Similarly values 240-255 was "push negative value on stack" with 255 push -1, 240 push -16. If you wanted to push larger immediate values you had to use one of the "push value on stack" bytes which took additional immediate arguments, similarly if you wnated to push values from registers with higher numbers than 16. Of course, this means that the lowest register numbers 0-15 are faster and easier to use than others

I used that engine to program a mud game once, for many years ago. Due to various reasons (real life) that mud game never got public but I got as far as having a server on my own computer which ran pretty fast.

The point with a stack based is of course that you define a higher level language (similar to C++ or some such) which people actually use. stack based means it is fast to execute and as such is an alternative to ERM but NOT an alternative to a high level language.

I don't know why slava chose not to use a stack based engine but I believe he had his reasons and so we have to live with that I assume he know very well about the concepts of stack engines and had a deliberate reason not to use such an engine, I am completely clueless as to what that reason would be though.

Alf

____________

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Odvin
Odvin


Promising
Famous Hero
posted August 25, 2003 09:48 PM

A few scripts in SERL

Now SERL is Structured Event Related Language - a hybrid of ERM and SQL

DROP HERO Isra - we dun like necromancers
ALTER HERO Halon ADD SKILL 'Water Magic' LEVEL 3 - let Halon be the Water Wizard
INSERT INTO HERO Gelu (Stack4, Stack5) MONSTERS ('60 Pikemen', '35 Archers') - now Gelu rocks... though he rocks anyways...

Now some extra sentences:
CAST SPELL 'Ice Bolt' BY HERO Alagar TARGET AT '7 Ogre Magi' - R.I.P. Ogries...
CREATE OBJECT 'School of War' AT (30, 18) - no comments

And the most awesome...
DROP PLAYER Red lol
____________

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Alf
Alf

Tavern Dweller
posted August 26, 2003 01:02 PM

Quote:
Now SERL is Structured Event Related Language - a hybrid of ERM and SQL

DROP HERO Isra - we dun like necromancers
ALTER HERO Halon ADD SKILL 'Water Magic' LEVEL 3 - let Halon be the Water Wizard
INSERT INTO HERO Gelu (Stack4, Stack5) MONSTERS ('60 Pikemen', '35 Archers') - now Gelu rocks... though he rocks anyways...

Now some extra sentences:
CAST SPELL 'Ice Bolt' BY HERO Alagar TARGET AT '7 Ogre Magi' - R.I.P. Ogries...
CREATE OBJECT 'School of War' AT (30, 18) - no comments

And the most awesome...
DROP PLAYER Red lol


I thoroughly oppose the idea of an SQL based language. I hope you proposed it as a joke.

Seriously, I do have some ideas concerning the HLL for ERM however, I lack the experience of those who have written many ERM scripts. I just looked at ERM and found it to be horribly difficult to understand (first impression) and thus got on the idea of making a high level language to translate from more "readable" code to ERM.

I don't think we need as many object types as Irh suggested. As long as an object type isn't handled in a special way by ERM we can treat it the same as any other "generic" object. Thus, I assume we will have the following types, feel free to add more if you feel there are some that I have missed.

First the baaic types, these translate directly to variables we can create etc.

bool
int
string

These types only have the properties of their values and the operations are the obvious once as taken from C language.

Second the game related types which I immediately can think of that we need.

object   - any object that doesn't fit in any other category  but which needs to be referenced can be referenced through an 'object'. An object have a location where it is placed and otherwise contain a pair of fields with values. I.e. you can set a field and if that field doesn't have a value already it will attempt to set it provided ERM will allow you to set that field with that object.

It is possible we end up with removing the object as a type if all ERM types get on the list so there are no objects that will ever need to be referenced as 'object'.

team  - a collection of players, 'human' and 'computer' and 'all' are pre-defined teams with the obvious meanings. A value is a set of players such as 'red, green, blue'.
A player is simply identified by a bit in a bitmask with special values for 'computer' and 'human' and a team is then simply a collection of those bits, i.e. a mask with all bits set for those players that are member of the team. The team of all players not in this team is then ~teamvar if we use C syntax with ~ for inverting all bits.

player - a single player, during certain events you have variables that contain player values, otherwise you can refer to red, green, blue etc. You can make a collection of these to form a team.

hero - a hero - has several attributes and during certain events you have variables that references specific heroes (this hero, opponent hero in a battle etc). You can also use a hero's name to reference a hero using cast syntax:

hero("Solmyr")  would be the hero object for the hero named Solmyr. If it is obvious from context that a hero is expected you don't have to do an explicit cast but use the name instead. If the hero's name is a single name without apostrophes, space or anything like that you might even drop the quotes and just use hero(Solmyr) or simply Solmyr if it is unambiguous.

Internally, a hero is simply an integer holding the hero index.

army - a collection of stacks of creatures but without a hero. This is a chopped down version of a hero object - or - a hero may be thought of as referencing an implicite army being the army of the hero. A city's garrison is also typically an "army" etc.

monsterstack (or perhaps only monsters) is a single stack of monsters, an army is a collection of these. A monsterstack has two important attributes while not in battle - the monster type and count - while in battle they would also have hit points for the top monster of the stack, i.e. when hitpoints drop to 0 the count decrease by one and the hitpoints are reset back to max. We would possibly also have other attributes as well - not sure how much you can manipulate through ERM during battle yet.

An army is seldom (if ever?) referenced by itself, it is typically found in these contexts:

1. A hero have an army that follows him along.
2. A city have an army in the garrison.
3. An army may stand some place ambushing heroes that comes along.

It is only the latter form which appear explicitely and I am not sure how that is handled in ERM yet.

building - this is just an ID of a building inside a city, a city typically contain a collection of buildings which is built and a collection of buildings which it is able to build at any time. This is typically implemented as an integer either holding the bit number for the building or a mask with one bit set identifying the building in question. The building collection is a bit mask.

buildings - as just said, this is a collection of buildings. It is simply a bitmask with bits set for the building. When asking for a specific building you must always keep track of which city type it is since - as far as I know - the cities overlap their use of building bits, so bit X for a tower city might mean one type of building while the same bit for a Fortress city means something else.

dwelling - this is a building outside a city which may produce creatures and the hero can pick them up.

mine - this is a building outside a city which may produce resources for the hero if he has the mine flagged.

resource - a resource is an object which references a resource type such as 'gold', 'ore' etc. so possible value for a resource type is "gold".

resource x = gold;

It is simply an integer with one value for gold, another for ore etc. The values match ERMS format tables.

For each of the resource types we may have a quantity of resources, for example an attribute of the player object is how much gold or ore you have, this is simply properties of the player object and the value is an integer giving the quantity. There's no 'gold' type or 'ore' type per se.

spell - a spell is an object which identifies a particular spell. Properties of spells are what type of magic they belong to, what level etc etc. Not sure how much you can get/set through ERM but essentially everything you can get/set through ERM related to spells are properties of a spell object.

spells - collection of spells. This can be used to describe the spells a specific hero knows or it can be used to describe what spells a specific city can teach. We might also have some predefined collections such as waterspells, earthspells, level3spells etc.

A typical operation might be:

if (spell in spellcollection) {
  .....do something here...
}

For example a city object's spellcollection is then the collection of spells that the city can teach and a hero object's spellcollection are all the spells the hero knows. Actually a hero have two spell collections, one is the spells he is able to cast and the other is the spells he has in his spell book (not counting scrolls and spells provided by other artifacts).

itemtype - itemtype is an object which references a specific item (artifact) type such as "medal of honor" etc. It does NOT reference a specific artifact as in "the medal of honor that is located at position X,Y,Z). It can be implemented as a simple integer holding the ID of the artifact type.

item = this is a specific artifact located in a specific place, it can be on the map in position X,Y,Z or it can be in the hands of a specific hero.

powerup - is a building located on the map which is able to give the hero some bonus or other effect. It can be resources, it can be to increase level (tree of knowledge) or increase a specific skill.

pskill - while we're talking about skill, there are 4 types of primary skills (attack, defense, power and knowledge) and the value of a pskill is simply one of those values. Just as for resources, the skill value is simply an integer so if you want to ask a hero's attack you stuff the value in an integer variable so int k = Solmyr.attack; would store Solmyr's attack into the variable k.

sskill - secondary skills are if I remember correctly (been playing heroes IV lately so my memory might get a bit confused) 14 in total and sskill is a variable type that references a specific secondary skill. The level of a secondary skill is a separate type.

lvlsskill - secondary skills have named level values (novice, advanced, expert and master if I remember correctly) and this type is like an enumeration fot those values. Internally it is an integer with the obvious encoding (direct match to ERM's values for the same).

position - position is used often in erm in the format X, Y, Z so we might benifit from having it as a specific type. This is simply an object which has three porperties the x, y and z coordinate. It is typically implemented using three integer variables in sequence.

I am not sure if I have covered all but I believe this should cover most stuff. Some final notes about implementation.

I have in the above said that some are implemented as an integer etc. What this means is that you can stuff it in an integer variable. Of course, if you store a Hero into variable k and then later sets another hero's knowledge skill equal to k + 2 you just picked that first hero's index and set the second hero's knowledge skill to that index + 2 - probably not very meaningful. It is to prevent that that I suggest we have those types so you can declare the variable as

hero h;

instead of just

int h;

and then since the type is 'hero' the high level language will prevent you from doing such silly things as I indicated above - it will at least give a warning.

Another note is about the powerup objects. What you can do with them is fairly generic and generally any map object (dwelling or powerup and possibly army and item objects as well) can be used to trigger some action in ERM which comes in addition to their regular action in heroes. a powerup can of course do nothing at all, objects which are only for viewing or blocking but which really doesn't do anything can therefore be referenced as a 'powerup' but it will of course not enhance the hero who meets it in any way. Similarly, a powerup can actually be a powerdown if it reduces morale etc instead of increasing it. As such it might be better if it has another name than 'powerup' I welcome any suggestions

On the other hand, the name 'powerup' does indicate its primary meaning, it is buildings on the map that temporarily or permanently modifies the current player or the hero which trigger the building's properties in some way.

As a general layout of the program I believe we can have the script as a sequence of declarations. First should come declarations of global properties or global effect - alternate names of heroes etc, for example if you chose to rename a hero to "Frodo Baggings" you might declare:

hero Frodo use ".....";

where you in the .... picks some hero with characteristics that are similar to what you want Frodo to have. You can probably change some of those in the script - for example give him some other skills etc so it doesn't have to be a complete match.

Then later in the script whenever you use Frodo it will reference that specific hero.

Similarly, you can declare global variables.

int k use 75;

The "use 75" is optional and if you don't provide it the compiler will find a "free" variable and associate that with the variable k. So whenever you do:

k = some_expr;

in the code, it will assign that to variable 75. Note that "free" is in quotes since the compiler can of course not know if the variable is really free. However, it will have a list of pre-allocated variables and then for each "use" clause for variables it will mark them as no longer free and if you then have a variable without any use clause it will pick a suitable free variable. Again, I understand that it is a convention in ERM to separate the variables in two blocks (above and below 500) and so it should probably select a free in the 500+ section and if you want a lower number you must specify it yourself or perhaps use some non-numeric keyword to speciay a low number variable slot.


Simiarly, you should declare the teams in the early part of the script:

team goodguys use red, green, blue;
team neutral use orange;
team badguys use ~goodguys & ~orange; // all the rest are bad guys.

This declares the teams and you can later in the script use 'goodguys' to reference the group of players red, green and blue.

After the global section should come the pseudo event handler for the "loading map event". The statements inside that event handler is translated into ERM instructions and are placed early on. I believe ERM allow instructions to be placed anywhere, can anyone give a good reason why this should be allowed? I am thinking of restricting ERM "instructions" to be in the early part of the ERM script, will this make some features problematic? As I know they are executed first anyway - before anything else so it doesn't matter where they are placed.

After the global event you write all the other event handlers and the code inside those will be the receivers. I know that ERM is organized in the way that you typically have a syntax like this:

T R R R R T R R R R

Each T and R is an ERM statement and all the R's are structured to belong to the T that preceedes it.

Thus, we write something like this:

event EVENTTYPE [IDENT] (PARAMTERS)
{
  STATEMENTS
}

The lowercase word 'event' is literally, the uppercase words are placeholders. EVENTTYPE is taken from a predefined word such as "BattleBegin" or "HeroMeetHero" or "HeroLevelUp" or some such. Some events have an identifier - if they do you write that immediately after the event type and before the left parenthesis.

Inside the parenthesis are parameters for the event. These are all determined by the event type, i.e. the type and count of parameters are chosen from that, you provide names for those parameters which you want to reference in the statements. For example HeroMeetHero would probably have the  current hero, the hero he or she meets and the position on the map where they meet as parameters so:

event HeroMeetHero (hero me, hero other, position where)
{
   if (other == Solmyr && ! AlreadyMet) {
      say "Finally you met your friend, he gives you a longbow";
      me.items += longbow;
      me.attack += 3;
      if (archery in me.sskills && me.archery < master)
        me.archery++; // improve the archery skill.
      AlreadyMet = true;
   }
}

STATEMENTS contain C-like statements to manipulate objects in respond to this event. As in C99 and C++ you can declare local temporary variables in statements.

So, what do you think guys? Any suggestions of improvement, does this look ok? I will most likely start working on it during the coming weekend. Maybe start earlier if I get time

Alf

____________

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Jump To: « Prev Thread . . . Next Thread » This Popular Thread is 407 pages long: 1 2 3 4 5 ... 80 160 240 320 400 ... 403 404 405 406 407 · «PREV / NEXT»
Post New Poll    Post New Topic    Post New Reply

Page compiled in 1.3086 seconds