Warscale 33 - Back to work
by Guimo · 02/10/2009 (5:14 am) · 11 comments
Hi all those brave souls who day to day devote time and energy on the development of their dreams! And cheers to those who leave their work to read these series.
Im sure some of you were already thinking -Thank god this guy stopped writing his blog all weeks-. Unfortunately for you I was just resting. As my Alpha release was scheduled for January 15 and I finished the first days of January, I decided to take some days off and rest. Its nice because you rest your brain and make you see things in perspective. On the other hand its dangerous because your mind may start wandering to that other project you always wanted to start... bad move... fortunately my wife is always there to whip me and chain me to my PC and force me into Warscale so here I am.
What was planed
Player registration screens (aborted)
I started again coding the registration screens. First I wanted to allow some registration from the GUI but at the end I think the best way will just be to create the login and account management directly from the web site. That way it will be easier to integrate to the game store (the one you use to buy gold pieces which you will use to buy models in the game). So, I decided to drop all those screens and just add links to the appropiate web pages.
Login screen with the two links for account creation and pw retrieval. Suggested logo. The background may not be the final one.
[image][/image]
GUI Bug fixes
There were a lot of bugs which appeared when I resized the screen. Mostly were simple things like objects changing places or objects not resizing. I have fixed all those things now. Of course there will come more.
More control of the GUI
Now each screen has its own input manager so I can program individualized shortcuts for each screen. None needed yet but its nice to have the option.
What wasnt planned
Animated GUI controls
This is a funny one. I was writing the bug fixes and thought... I really want a nice fade effect. Something like Warcraft3 where the screen layers come into view from the sides of the screen and when you get to the next screen it goes away and comes again... I thought -I will make that on the next stage-. But suddenly I thought... there is no later stage you idiot!!!! You are moving to beta!!!! If you want something do it now!!!!
So I decided to tackle the problem. There is a nice resource in the Plasic Gems about moving the controls but what I needed was something simple. Lately I'm tring to avoid touching the engine and do most of my implementations as scripts unless I have no other way to do it or there is a performace problem. So I decided to create an animation manager. The idea is simple. Add a control to the manager and tell it the position you want to reach, in how many milliseconds and if its a linear or accelerated movement (or deaccelerated). The class will compute all the movement values, will create an animation thread which execute each 32 msecs (of course it depends in the engine mood) and will move the object to its final destination correctly considering the screen positions as floating point values (for increased movement precision). Once the destination is reached, an optional callback is invoked.
Finally, I created a hide and a show method for each screen. The show method pushes the screen into the canvas but locates the controls out of view and then adds the controls to the animation manager so that they are animated to their final position. The motion is decelerated so they enter fast and gracefully stop at the destination. The hide method accelerates the controls out of view and executes a callback. So when I want to change from a screen to the other I do something like:
hideThisScreen("showOtherScreen();");
That command will execute the hide animation of the controls on the first screen and when it finishes will push the new screen to the ccanvas and animate the controls in. The result is a nice transition without a fadeout screen.
Of course this technique will be part of the Warscale GUI Code Pack which Im planning to release... if I ever manage to get anyone in GG interested. If you really need it look at the Snippets section :)
New shard selection
My original plan for the shard selection was to have a map in the background and make servers appear as places in the map. Nice concept but impractical. I dropped that concept in favour of a simple list of objects.
Screen names
I created some tags using Photoshop so that the player knows on which part of the game he is at any moment. By the way while doing this task my Photoshop died and didnt want to start up again, not even reinstalling worked, had to install and run as another user but at last it came back... a complete day of work lost.
Improved army information while editting
When editting an army the game now gives more information on the army like how many creatures, sorceries or artifacts are in the army, if the army has changed and needs to be saved, if you have included units not in your collection and the cost to complete the army.
Grid column resize cursor
When the mouse is in an area where you can resize a grid column, the cursor changes appropiately to suggest the function.
But units from the Army Editor
When you build your army and are missing a unit, the editor tells you how many units you are missing and shows the price of those units. You may then click the Buy button to get those units. Its a quick way to buy units instead of going to the Model Store. I had completely forgotten this feature. Fortunately all the buy procedure is already in place so it was fairly easy to hack it and add this feature to the Army Editor in just a couple of hours.
[image][/image]
Improved model store
The model store worked fine but it was confusing. I cleaned up the behaviour so now its easier to use.
Plan for next weeks
Im in search for nice 16x16 icons representing Creatures, Sorceries and Artifacts to use in the filters for the editors. I will continue with the game creation dialog and the game room.
Snippet
If you are interested, here is the script code for the control animation manager:
Add the previous code to a file and link it to your scripts. Now lets create an animation manager and add an object:
$WSGUIAnimationManager = WSGUIAnimationManager_create(); //Create the animation manager
$WSGUIAnimationManager.add(bmpMyBitmap, "500 500", 600, -1); //Make the bitmap move to position 500,500 in 600msecs decelerating.
$WSGUIAnimationManager.setCallback("echo("The control reached its destination!!!");");
Well, I hope this helps somebody.
Finally...
I'm in need of a 3DSMax exporter which can handle the ZBillboard (BBZ) flag. I tried to compile the code from TGE and it compiled fine but wasnt accepted by 3DS. If you are so kind to share this exporter please send it. Max 7 or 9 if possible.
Luck!
Guimo
Im sure some of you were already thinking -Thank god this guy stopped writing his blog all weeks-. Unfortunately for you I was just resting. As my Alpha release was scheduled for January 15 and I finished the first days of January, I decided to take some days off and rest. Its nice because you rest your brain and make you see things in perspective. On the other hand its dangerous because your mind may start wandering to that other project you always wanted to start... bad move... fortunately my wife is always there to whip me and chain me to my PC and force me into Warscale so here I am.
What was planed
Player registration screens (aborted)
I started again coding the registration screens. First I wanted to allow some registration from the GUI but at the end I think the best way will just be to create the login and account management directly from the web site. That way it will be easier to integrate to the game store (the one you use to buy gold pieces which you will use to buy models in the game). So, I decided to drop all those screens and just add links to the appropiate web pages.
Login screen with the two links for account creation and pw retrieval. Suggested logo. The background may not be the final one.
[image][/image]
GUI Bug fixes
There were a lot of bugs which appeared when I resized the screen. Mostly were simple things like objects changing places or objects not resizing. I have fixed all those things now. Of course there will come more.
More control of the GUI
Now each screen has its own input manager so I can program individualized shortcuts for each screen. None needed yet but its nice to have the option.
What wasnt planned
Animated GUI controls
This is a funny one. I was writing the bug fixes and thought... I really want a nice fade effect. Something like Warcraft3 where the screen layers come into view from the sides of the screen and when you get to the next screen it goes away and comes again... I thought -I will make that on the next stage-. But suddenly I thought... there is no later stage you idiot!!!! You are moving to beta!!!! If you want something do it now!!!!
So I decided to tackle the problem. There is a nice resource in the Plasic Gems about moving the controls but what I needed was something simple. Lately I'm tring to avoid touching the engine and do most of my implementations as scripts unless I have no other way to do it or there is a performace problem. So I decided to create an animation manager. The idea is simple. Add a control to the manager and tell it the position you want to reach, in how many milliseconds and if its a linear or accelerated movement (or deaccelerated). The class will compute all the movement values, will create an animation thread which execute each 32 msecs (of course it depends in the engine mood) and will move the object to its final destination correctly considering the screen positions as floating point values (for increased movement precision). Once the destination is reached, an optional callback is invoked.
Finally, I created a hide and a show method for each screen. The show method pushes the screen into the canvas but locates the controls out of view and then adds the controls to the animation manager so that they are animated to their final position. The motion is decelerated so they enter fast and gracefully stop at the destination. The hide method accelerates the controls out of view and executes a callback. So when I want to change from a screen to the other I do something like:
hideThisScreen("showOtherScreen();");
That command will execute the hide animation of the controls on the first screen and when it finishes will push the new screen to the ccanvas and animate the controls in. The result is a nice transition without a fadeout screen.
Of course this technique will be part of the Warscale GUI Code Pack which Im planning to release... if I ever manage to get anyone in GG interested. If you really need it look at the Snippets section :)
New shard selection
My original plan for the shard selection was to have a map in the background and make servers appear as places in the map. Nice concept but impractical. I dropped that concept in favour of a simple list of objects.
Screen names
I created some tags using Photoshop so that the player knows on which part of the game he is at any moment. By the way while doing this task my Photoshop died and didnt want to start up again, not even reinstalling worked, had to install and run as another user but at last it came back... a complete day of work lost.
Improved army information while editting
When editting an army the game now gives more information on the army like how many creatures, sorceries or artifacts are in the army, if the army has changed and needs to be saved, if you have included units not in your collection and the cost to complete the army.
Grid column resize cursor
When the mouse is in an area where you can resize a grid column, the cursor changes appropiately to suggest the function.
But units from the Army Editor
When you build your army and are missing a unit, the editor tells you how many units you are missing and shows the price of those units. You may then click the Buy button to get those units. Its a quick way to buy units instead of going to the Model Store. I had completely forgotten this feature. Fortunately all the buy procedure is already in place so it was fairly easy to hack it and add this feature to the Army Editor in just a couple of hours.
[image][/image]
Improved model store
The model store worked fine but it was confusing. I cleaned up the behaviour so now its easier to use.
Plan for next weeks
Im in search for nice 16x16 icons representing Creatures, Sorceries and Artifacts to use in the filters for the editors. I will continue with the game creation dialog and the game room.
Snippet
If you are interested, here is the script code for the control animation manager:
//WSGUIAnimationManager.cs
//The GUI Animation manager helps animating objects around the screen
//The manager takes a list of objects, target positions and time and will take care of the animation of all those objects
//When an object reaches the target location, the object is removed from the managed list.
//When there are no more objects in the list, a callback function is invoked
//While animating, the manager cover the canvas with a large invisible bitmap enough to cover all the area in order to prevent anyone to handle buttons
function WSGUIAnimationManager_create() {
%am = new ScriptObject(WSGUIAnimationManager);
%am.callback = "";
%am.list = "";
%am.animationThread = 0;
%am.bitmap = new GuiBitmapCtrl() {
canSaveDynamicFields = "0";
Profile = "GuiDefaultProfile";
HorizSizing = "width";
VertSizing = "height";
Position = "0 0";
Extent = "1024 768";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
hovertime = "1000";
bitmap = "dummy";
wrap = "0";
};
return %am;
}
//Sets the callback function
function WSGUIAnimationManager::setCallback(%this, %callback) {
%this.callback = %callback;
}
//Clear all the entries and the callback (just to make sure)
function WSGUIAnimationManager::reset(%this) {
if(isEventPending(%this.animationThread)) {
cancel(%this.animationThread);
%this.animationThread = 0;
}
%this.callback = "";
%this.list = "";
}
//Release the list and deletes the list object
function WSGUIAnimationManager::flushAll(%this) {
%this.reset();
%this.bitmap.delete();
}
//Adds an object to the list
//The destination is a point "x y", time in milliseconds
//The first object which enters the list will start an animation thread
//mrvu means animation will be done using acceleration, 1 = positive acc, 0 = mru, -1=negative acc
function WSGUIAnimationManager::add(%this, %control, %dest, %time, %mruv) {
//Decompose the destination as direction and distance and create a speed = dist/msecs component
%pos = %control.getPosition();
%dir = VectorSub(%dest SPC "0", %pos SPC "0");
%dist = VectorLen(%dir);
%dir = VectorNormalize(%dir);
if(%time <= 0)
%time = 1; //Wont accept space time paradox
%control.WSAMDest = %dest;
%control.WSAMDist = %dist;
%control.WSAMDir = %dir;
%control.WSAMTime = %time; //Will use it as the remaining time
%control.WSAMPos = %pos SPC "0"; //Base location in floating point precision
%control.WSAMMRUV = %mruv; //Is it acceleration based?
%control.WSAMDelta = 0;
//d = vo*t + 0.5 * a * t * t
//vf = vo + a * t
if(%mruv == 1) {
//Positive acceleration, vo = 0
%a = 2 * %dist / (%time * %time); //Compute the acceleration
%control.WSAMSpeed = 0; //Starting vel
%control.WSAMAcc = %a; //Acceleration
}
if(%mruv == 0) {
//Acceleration = 0
%control.WSAMSpeed = %dist / %time; //Speed in milliseconds
%control.WSAMAcc = 0;
}
if(%mruv == -1) {
//Negative acceleration, vf = 0
%a = 2 * %dist / (%time * %time); //Compute the acceleration
%control.WSAMSpeed = %a * %time;
%control.WSAMAcc = -%a;
}
%this.list = trim(%this.list SPC %control);
if(%this.animationThread == 0) {
%this.animationThread = %this.schedule(16, animate);
%this.lastTime = getRealTime();
//Cover the canvas
%content = Canvas.getContent();
%ext = %content.getExtent();
Canvas.pushDialog(%this.bitmap);
%this.bitmap.setExtent(getWord(%ext,0), getWord(%ext,1));
}
}
//Animate the control. This should be called
function WSGUIAnimationManager::animate(%this) {
%thisTime = getRealTime();
%delta = %thisTime - %this.lastTime; //Time since the last call
%this.lastTime = %thisTime;
%remove = "";
%list = %this.list;
for(%i = 0; %i < getWordCount(%list); %i++) {
%control = getWord(%list, %i);
%pos = %control.WSAMPos;
//Get the animation time and reduce this time from the remaining time
%control.WSAMDelta += %delta;
if(%control.WSAMDelta >= %control.WSAMTime) {
%remove = %remove SPC %control;
%px = mFloor(getWord(%control.WSAMDest,0));
%py = mFloor(getWord(%control.WSAMDest,1));
%control.setPosition(%px, %py);
}
else {
//d = vot + 0.5att
%pos = VectorAdd(%pos, VectorScale(%control.WSAMDir, %control.WSAMSpeed * %control.WSAMDelta + 0.5 * %control.WSAMAcc * %control.WSAMDelta * %control.WSAMDelta ));
%px = mFloor(getWord(%pos,0));
%py = mFloor(getWord(%pos,1));
%control.setPosition(%px, %py);
}
}
//Remove controls which have time less than 0
%this.list = removeFromString(%this.list, trim(%remove));
//If the list is not empty, schedule the movement again
if(getWordCount(%this.list) > 0)
%this.animationThread = %this.schedule(16, animate);
else {
%this.animationThread = 0;
Canvas.popDialog(%this.bitmap);
if(%this.callback !$= "") {
eval(%this.callback);
}
}
}Add the previous code to a file and link it to your scripts. Now lets create an animation manager and add an object:
$WSGUIAnimationManager = WSGUIAnimationManager_create(); //Create the animation manager
$WSGUIAnimationManager.add(bmpMyBitmap, "500 500", 600, -1); //Make the bitmap move to position 500,500 in 600msecs decelerating.
$WSGUIAnimationManager.setCallback("echo("The control reached its destination!!!");");
Well, I hope this helps somebody.
Finally...
I'm in need of a 3DSMax exporter which can handle the ZBillboard (BBZ) flag. I tried to compile the code from TGE and it compiled fine but wasnt accepted by 3DS. If you are so kind to share this exporter please send it. Max 7 or 9 if possible.
Luck!
Guimo
#2
02/10/2009 (7:10 am)
You really do create fantastic, well thought out, detailed, intelligent, informative blogs.
#3
02/10/2009 (7:23 am)
Hey Guimo, Nice work.
#4
02/10/2009 (8:24 am)
Glad to read on about Warscale. Beta is right around the corner, very exciting!
#5
02/10/2009 (9:02 am)
This is very interesting code snippet. I have to save this and try it out. Thanks!
#6
02/10/2009 (10:03 am)
As always, great work. I'm looking forward to trying this game out.
#7
02/10/2009 (11:20 am)
Quote:Im sure some of you were already thinking -Thank god this guy stopped writing his blog all weeks-.Wrong ;-) Great stuff as ever!
#8
Nice write up, but then you always do offer a lot of information and insight. That code snippet looks interesting too!
02/10/2009 (11:57 am)
Quote:Im sure some of you were already thinking -Thank god this guy stopped writing his blog all weeks-.Actually, I was just wondering the other day what was happening with Warscale.
Nice write up, but then you always do offer a lot of information and insight. That code snippet looks interesting too!
#9
Great write up and work, as usual.
02/10/2009 (1:50 pm)
Huzzah for the return of Warscale blogs! Quote:Now each screen has its own input manager so I can program individualized shortcuts for each screenInteresting. Could you elaborate on how you came to this solution? Did you try other methods first?
Quote:there is no later stage you idiot!!!! You are moving to beta!!!! If you want something do it now!!!!Awesome =) Very smart self discussion there. Every developer needs that little voice of reason to yell at them from time to time.
Great write up and work, as usual.
#10
@Novack
No... I dont have another blog. I have a domain and a website and it provides blog tools and all but Im just too lazy and busy to set everything up. Maybe I will ask my wife to do it but I just like posting here.
@Rollerjesus
Amazing name yo have :). Beta is still far away... June on my computations. But working hard to save some time. Sometimes I find things which I thought were missing and are already implemented... like today I was ready to add passwords to the games so you can invite only your friends and found it was already implemented and working! I dont know when I did it. So I just added some CRC encoding to the password and that was all! I hope everything continues as expected.
At John E. Nelson and Michael Hall
If you try this code, I found its better to invoke the callback with a slight delay. Change:
//eval(%this.callback);
schedule(64, 0, eval, %this.callback);
@Michael
The idea was that I wanted a screen to answer to its own keys. Having a global action map just wont work so I decided to create an action map for each screen. Its really easy.
Each gui file has its own cs as usual. On the CS I created an action map like:
//Define the default key handler for this screen
if (isObject(EEActionMap))
EEActionMap.delete();
new ActionMap(EEActionMap);
... Add your keys here to the action map.
Now, in the onWake of the screen I push the action map and on the onSleep I pop it. That way when I change the screen the action map is pushed on the stach and any key redefinition takes precendence over any global definicion while that screen is turned on. Simple.
By the way Michael, may it be possible to contact somebody at GG to discuss an idea for publishing some code packs. Same idea as an starter kit but with other approach. Please send me your email so I can send you details on the idea. guimo at spritekin dot com
Luck to all!
Guimo
02/10/2009 (3:01 pm)
Thank you all for your comments!@Novack
No... I dont have another blog. I have a domain and a website and it provides blog tools and all but Im just too lazy and busy to set everything up. Maybe I will ask my wife to do it but I just like posting here.
@Rollerjesus
Amazing name yo have :). Beta is still far away... June on my computations. But working hard to save some time. Sometimes I find things which I thought were missing and are already implemented... like today I was ready to add passwords to the games so you can invite only your friends and found it was already implemented and working! I dont know when I did it. So I just added some CRC encoding to the password and that was all! I hope everything continues as expected.
At John E. Nelson and Michael Hall
If you try this code, I found its better to invoke the callback with a slight delay. Change:
//eval(%this.callback);
schedule(64, 0, eval, %this.callback);
@Michael
The idea was that I wanted a screen to answer to its own keys. Having a global action map just wont work so I decided to create an action map for each screen. Its really easy.
Each gui file has its own cs as usual. On the CS I created an action map like:
//Define the default key handler for this screen
if (isObject(EEActionMap))
EEActionMap.delete();
new ActionMap(EEActionMap);
... Add your keys here to the action map.
Now, in the onWake of the screen I push the action map and on the onSleep I pop it. That way when I change the screen the action map is pushed on the stach and any key redefinition takes precendence over any global definicion while that screen is turned on. Simple.
Quote:Every developer needs that little voice of reason to yell at them from time to time.I guess shrinks will have other way of defining that voice :)
By the way Michael, may it be possible to contact somebody at GG to discuss an idea for publishing some code packs. Same idea as an starter kit but with other approach. Please send me your email so I can send you details on the idea. guimo at spritekin dot com
Luck to all!
Guimo
#11
Also, If I may, I think the person you need to contact for the code packs is Derek Bronson, he is in charge of third party products (all the way).
02/10/2009 (5:23 pm)
Guimo, its ok, its better this way, Im not at risk of missing any extra info on your advance :)Also, If I may, I think the person you need to contact for the code packs is Derek Bronson, he is in charge of third party products (all the way).
Torque 3D Owner Novack
CyberianSoftware