[Release]scene.bin ai size reduction project, v0.1

  • Thread starter Thread starter secondadvent
  • Start date Start date
Status
Not open for further replies.
@nfit1c: i believe that row 16 is the "can't reach" row, since zemzelet sets its row to row 16 when it flies up. oh, and imagine a fully ai controlled party... that would actually be pretty fun to do for boss battles (big ones)... see how long your ai lives against... your ai :-P.

@warbaque:  that is essentially right, but a way to make your second statement right (since putting just one nonzero value, say 23 for instance, could be wrong, even though it is still non-zero) would be to make if (something >= 1), because it will always be a (positive) non-zero value, though just if (something is much easier to write, and saves space :-P.
 
Last edited:
@warbaque:  that is essentially right, but a way to make your second statement right (since putting just one nonzero value, say 23 for instance, could be wrong, even though it is still non-zero) would be to make if (something >= 1), because it will always be a (positive) non-zero value, though just if (something is much easier to write, and saves space :-P.
My 1st statement was
If (something) is equivalent of If (something==1)
what would if statement return when using following value for example
something=0 If (something) returns 0
something=1 If (something) returns 1
something=23 If (something) returns 0
something=-23 If (something) returns 0

And second
If (something) is equivalent of If (something=/=0)
something=0 If (something) returns 0
something=1 If (something) returns 1
something=23 If (something) returns 1
something=-23 If (something) returns 1


Because in scripting languages I've been more recently working with
If Variable has been just shorter and more efficient way of using If Variable==1
 
actually, you have them reversed... if (something) returns true whenever the number isn't 0, so 346456456 would be true, 0 would be false. if (something == 1) would only return true when something is equal to one, so only 1 will ever return true, nothing else.

well, if (something=/=0) would work as if (something), but takes an extra three bytes in the ai to do, opposed to the if(something) method. if you use if (not(something)) in the ai (essentially an if(something == 0) statement), it does the exact opposite, and is good for whenever you ned to check something against the value 0, since it takes less room in the ai to do.

yay... blugu lost 99 of it's 262 byte size >:D. heh... and it looks like smogger isn't too much different ai-wise from the blugu, just an extra check, and a few modifications to add to make it work. just like with the MP and grunt enemies, since their ai was exactly the same originally (except moves used and random chances... exact same size)... i love it when enemy ai is the same (at least for this mod... overall that isn't a good thing >_>).
 
Last edited:
actually, you have them reversed... if (something) returns true whenever the number isn't 0, so 346456456 would be true, 0 would be false. if (something == 1) would only return true when something is equal to one, so only 1 will ever return true, nothing else.

well, if (something=/=0) would work as if (something), but takes an extra three bytes in the ai to do, opposed to the if(something) method. if you use if (not(something)) in the ai (essentially an if(something == 0) statement), it does the exact opposite, and is good for whenever you ned to check something against the value 0, since it takes less room in the ai to do.
If (something) works just as well as if (something <> 0). This includes negative values. The reason is the jump 70 which jumps if the popped value is 0. If the previous value is 0 then it jumps over all the next few statements. Also remember that just because things are compiled one way doesn't mean it's the only way to do it. Optimizing Assembler code is a huge task that requires you to know more than just the language it was written in.

And second
If (something) is equivalent of If (something=/=0)
something=0 If (something) returns 0
something=1 If (something) returns 1
something=23 If (something) returns 1
something=-23 If (something) returns 1
This is correct.
 
yeah... and i wouldn't recommend doing what i am doing, even to myself :-P. with programming the ai, there are many ways to do things, some are better than others, but none "have" to be done a certain way. you could intentionally make the ai do 10x the work to do something, but it could still get the same answer as something 1/10 the size.

the ai does a normal sized script in one frame of the game, so unless you loop things massively, or program really bad, and when i say this, i mean REALLY bad... like using 1kb for a common enemy that only has two attacks :-P, it shouldn't seem any different in-game.
 
yeah... and i wouldn't recommend doing what i am doing, even to myself :-P. with programming the ai, there are many ways to do things, some are better than others, but none "have" to be done a certain way. you could intentionally make the ai do 10x the work to do something, but it could still get the same answer as something 1/10 the size.

the ai does a normal sized script in one frame of the game, so unless you loop things massively, or program really bad, and when i say this, i mean REALLY bad... like using 1kb for a common enemy that only has two attacks :-P, it shouldn't seem any different in-game.
No kidding. Remember what I said about Eligor having the longest script? Pointless. Granted he's almost as hard as a boss at that point, but he's no WEAPON.
 
Since everything is init'ed to 0 then Attack will be 0 if AttackType is Command.Attack (1h). Otherwise it'll be Command.Magic (0h). So the odds of Sephiroth casting Quake3 are 1:3 IF there's not a monster that nullifies or absorbs Earth Elemental. Even though he has a Restore Materia, he will never use it in battle. You could get him to use it out of battle, I suppose. I never tried it. He'll also never use Fire3 on all enemies like this.
I always found it weird all other Sephiroths elemental spells had all materia linked to them except fire. Instead there was an empty slot. I always thought that this was a mistake on developers part but now I see AI tells different story.
Fire3 intentionally casted only on single enemies when normal attack would do ½ damage because of back row modifier. And because of that I think that casting Fire3 at all is impossible with this AI since if I understood "ElseIf ( (BitCount(AllActiveOpponentMask) == 1) )" correctly Sephiroth will only use normal attack and Fire3 against single targets. In vanilla scene.bin all enemies in flashback come in groups and Sephiroths kills them all in once either with Ice3 or Bolt3 and if for some reason 1 enemy was left alive it would always be in front row -> so no Fire3
Have I understood "ElseIf ( (BitCount(AllActiveOpponentMask) == 1) )" part correctly? Is this what actually happens?
 
im slowly approaching eligor as well... he is where i am at in my hard mod (old one, pre-ai scripting knowledge), and inever found him to be difficult even in a normal game... his ai is really long for any enemy in the game (at the current ai level in vii), and i plan on shortening that :-P. MP and grunt had 861 bytes each... more than even GS did total, and they shrunk down to ~250 apiece, while GS is still around the same original size (about 30-50 lower, but still  :-)).

i think that the row being 16 is the "can't reach" row, but since there isn't any enemies that can fly out of range in the flashback, i dont think it is ever used. otherwise, he should always use fire3/firaga on an out of range enemy. either way, the only way to know is to have his ai active on someone in an out of range enemy battle, or set your row to 16 with ai and have the enemy use it on you (same thing, just reversed). i am almost 100% sure that 16 is out of range row, so i am guessing that putting sephy against a zemzelet or heli gunner for instance (zem would have to be flying), he would always use fire3 until they died.

warbaque... i think you should learn the way to program it with opcodes rather than just in the normal code form, since even if you know how it should look in written form, it won't help you if you can't code it. a good place to fool around with learning ai is the MP fight at the start of the game, just skip the movie (gypt instant yamp) with ctrl+s, run forward when able to, and test your enemy guaranteed, no need to worry about any other enemies possibly showing up. then, when you are done, or it craps out, just quit out and change/try again, taking little time between modifications :-P. and even if your logic is right, there could be little errors (such as using wrong sizes for variables) that would still show correctly in the disassembled view... the more you know about the coding itself, the better off you are. not that learning how it should look is bad, it is just useless without learning the coding along side it.

almost ready to put a beta up for testing, since air buster is a few enemies away. the kernel update issue in PrC happened again, but no biggie. air buster is going to be a fun one though...

wow... i just looked ahead to eligor's ai, and it has 2693 bytes used for it's ai... that is REALLY bad... and i will probably make the scene.bin shrink a size by editing it's ai alone... what were they thinking?

taking a quick look at the scene files again to remove enemies that aren't used in-game (grunt at shinra building for example). should give some more room. at 256 kb currently, it's last scene lookup is now 246, so it is getting pretty close to shrinking yet again. checked the cactuar battle, and it wasn't affected by my scene file hex editing (removed the grunts in it's scene, as well as in scenes 63/64 (erased completely/all FF file), since they were not used), so things got a little boost in shrinkage safely :-P.
 
Last edited:
my game style must be odd I find eligor very easy, easy to the point I can just have 2 characters waiting whilst the 3rd one keeps attempting to steal the striking staff, he is not hard enough in that I need to heal and finish the battle.

in regards to peerless I meant adding the ability to enemies so they can use it, I wouldnt object to the player been able to use it ( I considered adding great gospel to cait sith as level 3 break or as a reward on his fruit machine) but it can be considered a cheap move.  I am not massively against cheap moves I think they are less of a problem than the overall too weak enemies.  Its one thing having cheap movies it is another thing when the cheap moves arent needed to easily win a battle.

secondadvent I think you have touched on the problem I noticed, when I was looking at the growth curve in wallmarket I wanted to see if I could make early growth much slower (like in oblivion) and it accelerates towards the end so higher levels are more rewarding and you not overpowered early in the game, some times when attack power increases there is very large boosts in attack been dealt as well.  In addition I would like to see different characters more variable in their stats.

So if barret is a tough guy we boost his max hp and max defense but we make his magical and dexterity abilities signifacantly worse.
Tife we boost her dexterity but we reduce her toughness and hitting power.
Cait sith we can make someone whos lucky and is good at magic but very weak physical abilities.
I would have vincent the 2nd best at magic in the game (behind aerith and ahead of cait sith), but weak at physical defense and dexterity.
Cid can be all round like cloud but weaker.
nanaki dexterity same as tifa but not so fast and of course not as weak.

So these are ideas to add variety which makes the player be more strategic in the use of characters.

There is one thing I wonder a lot in RPG's which squaresoft made an effort to fix in crysis core and that is why dont they add diffilculty levels, they have a problem in satisfying players new to the genre so dont want the game to be too hard and dont want to make it so the players have to train and level up their characters to get pass a boss, but this then makes the game too easy for experienced players, the solution is a diffilculty option, personally I think its better if a player needs to level up to get passed a point in the game then be in a position where the level is too high for that point of the game and things are too easy.
 
Last edited:
i know eligor is easy... it just has a massively high amount of ai it uses (basically repeating the same thing a million times). if you pump up it's stats it can be deadly though, as can any other enemy be if the game is balanced right.

peerless would be something i would give to enemies (stronger ones) as something similar to ffxii's paling, but for both phys  magical, and status resistance in one, and wears off quickly. however, manually setting enemies to be immune tho things with ai editing (setting phys/mag immunity on, dunno if status immunity is there/works or not yet) allows for a longer counter, which is dependent on their attack speed rather than in-game units of time.

i am not going to be adding anything yet, but after i finish up to and including air buster, i will be putting my mod up for testing (hopefully it shrinks to 248kb... it is close ^^), and starting my hard/balance mod up to air buster as well (kinda alternate between the two, compressing then making use of the compression. i hope you guys will help me out with the testing as well :-P.

the beta should be up either later today, or early tomorrow (3:30 pm here), since i will have to do school work here soon, which is very easy... my current class is an intro to programming course, teaching about pseudocode (not any actual language, just pseudo), and is my third full intro class, i have had a intro to java, C++, and half a COBOL class before this, all teaching pseudo as well, but i have to take this class to continue on... guess i will get another A then XD.

ok, the blood taste enemy's tentacle drain is physical based, and costs 0 mp, even though it seems as if it should be a magic attack in the ai (checks for mp as well). unlike it's previous palette swap, the guard hound, it cannot use the regular tentacle move. what i am thinking, is that it was normally supposed to have three attacks (bite, tentacle, and tentacle drain), and that the draining version was to be magical based with mp cost attached. if the ai supports this fully, it will be gaining an attack, and it's ai will be slightly altered from normal.

i think i will add the normal tentacle attack, and make it the attack used if it runs out of mp, essentially making it still use it's tentacle attack, just without draining capability, since the tenacle attack is stronger than the normal bite attack anyway. it will also replace the bite attack in another spot, where the possible double attack happens, making the second attack the more powerful tentacle attack, though it would only use this at lower life (commonly at least), so it is essentially a balancing attempt, but with weak enemies :-P. tentacle drain will be switched to magical damage, and the blood tastes given enough mp to use it a good bit, but i will not change their magical power, though i may have to reduce the atk power of the move to accommodate the type switch.

yeah... i checked, and if it were to just do a plain switch, it'd do ~78 damage a hit... if i reduce the power of the drain attack to 1 instead of 10, it'd do the same damage it does now, but in magical form. a really weak attack, but it would still be true to the original damage amount. then again i could keep it physical and just give it mp cost, but then it's magic power goes to waste... though at a 1/16 base power, at 255 magic and at lv 99, it'd only do ~130 damage, hardly anything. i think it will stay physical for now, but with an mp cost, since that works out the best overall.

also, i will be reversing all dropped/stolen items (not making steals drops, and vice versa, but the order in which they are gotten, making the rarer items drop first), since there was obviously a mixup in the layout, since some items are made extremely rare, some items completely missable after a certain point (vagrysk claw anyone?), when the rare item was supposed to be checked for first (giving the rare drops priority if the random number succeeded, instead of going through all common items first). this should help balance the normal drop/steal chances without actually changing the item or drop rates, making the common drops less common, and the rare drops more common.
 
Last edited:
Since everything is init'ed to 0 then Attack will be 0 if AttackType is Command.Attack (1h). Otherwise it'll be Command.Magic (0h). So the odds of Sephiroth casting Quake3 are 1:3 IF there's not a monster that nullifies or absorbs Earth Elemental. Even though he has a Restore Materia, he will never use it in battle. You could get him to use it out of battle, I suppose. I never tried it. He'll also never use Fire3 on all enemies like this.
I always found it weird all other Sephiroths elemental spells had all materia linked to them except fire. Instead there was an empty slot. I always thought that this was a mistake on developers part but now I see AI tells different story.
Fire3 intentionally casted only on single enemies when normal attack would do ½ damage because of back row modifier. And because of that I think that casting Fire3 at all is impossible with this AI since if I understood "ElseIf ( (BitCount(AllActiveOpponentMask) == 1) )" correctly Sephiroth will only use normal attack and Fire3 against single targets. In vanilla scene.bin all enemies in flashback come in groups and Sephiroths kills them all in once either with Ice3 or Bolt3 and if for some reason 1 enemy was left alive it would always be in front row -> so no Fire3
Have I understood "ElseIf ( (BitCount(AllActiveOpponentMask) == 1) )" part correctly? Is this what actually happens?
Not really. Like I have said, the disassemble is just an approximation and isn't always 100% accurate. This is one of those times. That particular piece isn't an ElseIf block, but an If block nested inside an Else block. Confusing, I know. Conditions are one of the harder things to decompile because jumps can go all over the place and there are frequently jumps that never get called that are throwing off the disassembly.
 
ok, blood tastes are done and able to use tentacle drain up to four times due to mp cost (still physical attack equation used),so only air buster is left before the beta arrives, but i have to finish school work first, so it could still be a few hours until then, plus i still have to do the initial testing of all the ai i recently edited (everyone between guard scorpion and air buster). i do not think it will reach 248 kb this release, but the next one will most certainly become that small :-P.

my goal is to try and reach ~200kb in size, but whether or not it can be shrunk that far is still unknown to me right now.

ok, now with a weeks worth of programming class homework done in two hours (a test included :P), i am now back in action >:D. sadly, it took me longer to finish that homework, which was easy, than it does to shrink a moderate sized enemy's ai... too used to ai editing right now i guess  :|

heh... by the looks of it, air buster will be a nice little challenge to optimize, and since i know what 402c is, i know the only unknown in it's ai :P. yay for the no death animation flag, which stops the normal death animation, usually for using custom death animations (in this case, he uses a different version depending on his facing), but can also be used to prevent the enemy from becoming invisible when killed and revived via ai (insta revive, non-invisible style, and without using a move to do it >:D). hmm... if there is a flag to enable the main script, maybe there is one to enable/disable others, more specifically the death counter, so multiple auto rezzes can happen in one fight.

i think i am going to test up until i reach him, just so i can get a better understanding of what all is possible to be removed without any changes to his performance. and this way all i have to do is test one fight before the beta is out :P.
 
Last edited:
Since everything is init'ed to 0 then Attack will be 0 if AttackType is Command.Attack (1h). Otherwise it'll be Command.Magic (0h). So the odds of Sephiroth casting Quake3 are 1:3 IF there's not a monster that nullifies or absorbs Earth Elemental. Even though he has a Restore Materia, he will never use it in battle. You could get him to use it out of battle, I suppose. I never tried it. He'll also never use Fire3 on all enemies like this.
I always found it weird all other Sephiroths elemental spells had all materia linked to them except fire. Instead there was an empty slot. I always thought that this was a mistake on developers part but now I see AI tells different story.
Fire3 intentionally casted only on single enemies when normal attack would do ½ damage because of back row modifier. And because of that I think that casting Fire3 at all is impossible with this AI since if I understood "ElseIf ( (BitCount(AllActiveOpponentMask) == 1) )" correctly Sephiroth will only use normal attack and Fire3 against single targets. In vanilla scene.bin all enemies in flashback come in groups and Sephiroths kills them all in once either with Ice3 or Bolt3 and if for some reason 1 enemy was left alive it would always be in front row -> so no Fire3
Have I understood "ElseIf ( (BitCount(AllActiveOpponentMask) == 1) )" part correctly? Is this what actually happens?
Not really. Like I have said, the disassemble is just an approximation and isn't always 100% accurate. This is one of those times. That particular piece isn't an ElseIf block, but an If block nested inside an Else block. Confusing, I know. Conditions are one of the harder things to decompile because jumps can go all over the place and there are frequently jumps that never get called that are throwing off the disassembly.
Not that confusing now that you explained. Seems like, as secondadvent said, I should use mainly opcodes while editing AI, not that hard after a bit of learning.
 
i advise you to start with a simple ai (like 1st ray) and work your way up to bigger, more complex ai. i am at air buster right now and i have to actually test the fight normally to know what is able to be removed, since it's ai is a big mess (not as bad as eligor's, but pretty bad). they made things complicated beyond what was needed, and i plan on fixing that :P.

try out some ai on the mp enemy (just use a fresh scene.bin and completely erase the main ai and start from scratch, it makes learning much easier. also, use the WM help file, and look into the ai section for a good many examples, and what the opcodes do. that is how i learned to do this, and i am putting it to good use >:D

at least now is a good time for me to compile a list of how the ai should react, lain out in an easy to follow way, so that i and other people will be able to test out my ai to make sure it is all working properly. i already have a list of changes to both size, and enemy moves/stats (only a few moves/stats altered so far, to better fit the ai), so that is one thing down.
 
Last edited:
oh yeah, but i know what is going on there, and could easily take it pretty damn low. if you notice, the same damn checks are performed over and over, rather than jumping to the very first time it is checked and working from there. writing something once and jumping back to it is more efficient and much easier to follow than writing it 100 times, but you have to model the program around it so that when other parts jump to it, everything flows right.

AB is my biggest enemy so far, having around 1150 bytes worth of code (shrunk ~20 so far in the death/pre-battle ai, and they were small to begin with), so it will take some time.

here is an example from my test file, showing what the enemies should do in a fight, like who is targeted, and the chances of using certain moves, but with better spacing obviously... it doesn't like to copy tabbing over >_>:

Grunt:   it's row   party's row      target      attack probability
           front      all in front      random      1/8 Beam Gun, 7/8 Handclaw
                       all in back      random      5/6 Beam Gun, 1/6 Handclaw
                       mixed rows   *              1/2 Beam Gun, 1/2 Handclaw
           back      all in front      random      7/8 Beam Gun, 1/8 Handcalw
                       all in back      random      15/16 Beam Gun, 1/16 Handclaw
                       mixed rows      *              11/12 Beam Gun, 1/12 Handclaw
*if the attack will be Beam Gun, it will always hit a back row ally, if Handclaw, always front row ally
 
Last edited:
I have no clue what it is exactly that you're doing... but once you're done, will the enemy's act more intelligently?  Not necessarily more difficult, but perform moves normally at their disposal at more appropriate times?
 
for this part of my mod, no. all that is being done is bugfixing the original ai (and adding things as needed when i think it fits into the original ai's layout, i.e. what i think was going to be there originally), and rewriting the ai to be much smaller while doing the same thing. this is essentially for those psx modders out there to have a nice base scene.bin to use that shouldn't ever go above the size limit unless you massively add things to the ai, and i mean a LOT.

however, after i release my current version (will be up to air buster), i plan on starting my hard/balance mod, which will be doing as much ais i can do to make them much more capable of kicking your ass. believe me, i have plenty planned, and the sad thing is, is that i will likely NEED the base ai compressed as far as possible to fit it all in to still easily fit into a psx iso. i will be compressing/bigfixing, then balancing/increasing difficulty, and going like that back and forth as i progress on, and when i make significant progress with the balance mod, it will gain it's own thread.

this part is just to make my, and other people's, life easier. i think people would be happy to have a mod they can easily use as a base for their projects, or for any who just wants to play a bugfixed version of the original, or as much as i have knowledge to do (i will try as hard as i can to find out the unknown variables, for better understanding of certain ai's and for future use).

i am currently at air buster, so when i complete his ai and do initial testing, a beta will be out for people to use, and my balance mod will start to take shape as well. i will have to completely remodel each enemy twice, once for this mod, and again for the balancing one, but it will be worth it in the long run. beta will be up sometime tomorrow, since school took some time away, and i am pretty damn tired XD.

i updated the first page into something hopefully more readable, especially since i will soon be releasing the first vesion (actually about version 0.05-0.1, but it is still a release :-P

ok, all enemies tested up to, but not including air buster (still need to see exactly how its ai works), an fixed the bugs i initially had (mainly just trying to put a value into another value instead of in an address... i hate when i do that >_>). at least my fixes didn't require any additions/rearranging, my program was right, but my little address errors stopped it from working right (actually all but one worked almost right, even with the errors for some reason :-P). now to work on air buster, test him, and then put my release up >:D.

his ai is currently giving me issues, i am still figuring out the facings and stuff for the battle (learning about special formations at the same time), but i should be making progress soon.
 
Last edited:
ok to bump up my thread some, and to add some ai info that i have been messing around with (air buster testing).

going to make an example of what happens during back/side attacks:  

party 1        party 2            party 3
facing= 1     facing = 1/0     facing = 0

ok, party one is the left side of the screen, and party three the right. when someone of one party attacks another party, and their facings are the same, the back attack damage occurs (same party would be guaranteed back attack, even though they are in the same row, which is why it doesn't work that way. it must be two different parties). so if cloud attacked air buster when it was facing barret (cloud's facing is 0, barret's facing is 1, and it is facing the same way as cloud, so AB's facing is 0), the back attack damage would kick in since they both have the same facing, and are in different parties.

back attack (enemy's back is facing you) keeps your facing at 0 like a normal fight (you get facing 0 as a base, and the enemy gets a base facing of 1), but the enemy's facing is also 0. in an ambush, your facing becomes one, like the enemy's base facing. a pincer attack would have the same layout as a side attack battle (not completely sure, haven't got to test one yet), the right side being facing 0, the left facing 1, and your party facing mixed ways.

the sideAttack flag is likely just to check which party someone is in during a back attack, used similarly to the facing flag, but likely to attack specific parties rather than a specific person (like when using an attack all move, it can only hit one party, probably unless the move hits everybody on the field). doing some testing on this flag now, will update about it soon.

ok, barret's backAttack flag is 1, and clouds' 0, just like the facings, so it is like a party facing a certain direction, and that direction is the flag for that party.

ok, finally getting it's ai slimmed down, but i am having to test as i edit, since i am not 100% sure on everything. the original ai has so many flaws it is unreal. they set the idle animation in places where it is not needed to be set, and the final hit has the wrong animation as well (acts as if cloud hit it when killed by barret/tifa, and vice versa). working on the counter ai first, since it is smaller and is easier to test (in a shorter time frame anyway). bodyblow is unusable when at under 20% hp (turn broken), since it cannot move.

if i cannot get AB done anytime soon, i will release the scene.bin as it is, which has everybody up to him finished and (hopefully) working. AB has a lot to optimize, and there are things i am thinking of adding (not sure yet though), so he will still be a while.

i dont think that it can use bodyblow unless it is attacked from behind (and if it's turn isnt broken) and at a 2/3 chance. the move itself turns AB around (and sets it to a new idle animation) like it does in the main ai. this is what was causing me trouble, as i couldnt figure out how the hell it was turning without the special attack added before it. should be pretty fast from here on out then ^^.

air buster's counter ai is now working properly (i hope), so all that is left is the main, and then it will be released.

update: ok, just some tweaking and then the mod will have it's first release! the ai is finished now, but there are still two bugs that were in the original ai (the wrong hurt animation on killing blow, meaning if facing barret and hit by cloud, it looks like he is facing cloud when the hurt animation plays, and if attacked in the back and then attacked in the front (if it doesn't use bodyblow as a counter, or turn using main ai), the back attack damage will still happen to an attack on it's front, probably because the game automatically reverses the flag when back attack damage is done). other than those two bugs, it should be working like normal.
 
Last edited:
ok the first release is out... let me know how things go ;).
 
Status
Not open for further replies.
Back
Top