| Want to print? Use this version|
Back issues are in the Archive
Go back to the main site
Download a zip version
Don't like frames? Kill 'em.
REM 'Letter from the Editor
What are those "specials" all about?
Heya! For those of you who don't usually visit in between issues, you may have noticed something new on our homepage. What are these new-fangled "specials"? Like I said last month, from now on you should expect a couple of articles a month in the weeks in between each issue, exclusive to then! The Letter from the Editor will then go over them, as I am here. Firstly, I compiled Petter's huge assembly series into a Word .doc and it weighs in at a heavy 72 pages of single spacing. You can find it here. In addition, I've written a pretty thick article on the palette, and some neat tricks for it, which is located right here. These should both open in a new window.
Who's our third hall of famer?
In addition to that, on a recommendation from Entropy, you can now kill the frame when you're reading, so that you can get a "full-screen" experience. Mind you, the graphics might looks sorta off if you do this and have a monitor at 1024x768 or higher, but your decision now ^_^. The link for that is right up with the Table of contents.
In the content of the mag, we hope we've got a good selection for you guys this month. With Petter's assembly series over, we were hoping to hit off with a bang, and possibly some of the stuff inside will do that for you. Gavan has also started a new article, one on some basic tile-drawing techniques. Gavan is, of course, the tile artist for Dark Ages 2, and if anyone knows art, it's him.
That's not all, either. Seav has an article on all sorts of graphical coding techniques and speedups, some common and some pretty unknown, in the start of his "Power Programming" series, which is perfectly based for the 99% of coders in the beginner/intermediate category. Alias has completed another selection from his series on Voxels, this time gettin' deep into the coding. I myself have a review of Bill McDonald's SpaceWar. This title was 2nd in Qlympics voting in the very challenging Adventure category at press time, and we tell you if it deserves it, especially since the title is in the same vein as upcoming games like FreeLancer and Space-a-Roo 2. syn nine's excellent looking Vampira is in the Gallery this month, and we also have a third addition to the hallowed hall of QB hall of Fame. Who will join DarkDread and Angelo Mottola? You'll soon find out.
In design related issues, the cgi voting version of the Survey has been delayed at least another month, mostly due my bad code ^_^. If anyone wants to help me make a cgi based form, that would send the results to my mailbox, contact me here. Also, you may have noticed we have a slightly different look over the entire website, with smaller pages. Would you guys like each article on it's own "page" in the magazine? It would probably look better, but printing would be more of a pain. Let me know your opinion!
Finally, we grabbed another two countries on to our list of where our readers are from (see last month's letter from the editor). Readers from Japan and Slovenia wrote in to tell us of their homeland! 21 countries are now on the board, which is super-cool. So, scroll down and enjoy...Issue 10.
Compiled by ZKman
The future of the QB4.5 IDE
What can be done? How about 2 new projects; one from Blackbird and one by Leroy. Both aim at taking qbasic into Windows, with the window mode run-times and extra speed that could be derived therein. Firstly, BlackBird is working on a project called "WinQB". It's a pure Windows port of the Qbasic IDE, which will give you full code compatibility and the extra memory to run your program with. It will also allow you to do stuff like run 2 programs at once windowed, etc..
Leroy is taking another route with his program, which will "translate" your qbasic code into DJGPP code, giving you run-time increases of up to 30 times, and allowing you to use Windows memory. Downsides do exist on this option, though, as well. For one, most assembly will have to be redone due to the differences in the way DJGPP will handle the code vs. Qbasic. Also, certain things like machine code and CALL ABSOLUTE won't work, because of differences in calls in the Windows environment vs. the DOS environment. Also, qb:tm suspects that the majority of coders will not recognize such programs as QB programs.
Although both of these projects are a ways from completion, they both look to move qbasic forward into the next era for the language, and luck is wished to both!
WindowsQB?, Demo Scenes, and more
The QB Demo Scene resurgence
Demos started in the early 1980's when cracked programs (games with the security removed) appeared, with the cracker usually putting some kind of graphics show as a symbol of who cracked it. The demo scene then broke off from the cracker scene, and many professional coders have got their start with the graphically advanced demo.
DirectQB 1.6 and Dash2
Angelo Mottola has been nice enough to give us your first look at the specs for Directqb1.6. Here y'are!
Oh, and maybe Majiko should look up his titles in Spanish (heh...ChiChi).
Is Killerz Strip Fighter?
However, to our regret, we failed to mention that, yes, Nekrophidius knows that he is using these images. They are from a TurboGrafx16 game called Strip Fighter II, and will probably not end up as final art.
Dorothy, We're home again
Vertical Scroller named
...Beam me up, Scotty
The question is, will it hold up to the other 2 competitors? Pasco's Freelancer features squad-based enemies with nice AI, in a very fast, smooth-scrolling, and easy on the eyes graphics in that title, with a great demo released recently here. SonicBlue is taking a slightly different approach, with 8-level instead of vertical scrolling for Space-a-Roo2, and this is already shaping up as one of the most interesting titles of 1999, with a great physics model and some nicely varied enemy types, as well as the promise of much more. In qb:tm's opinion, SaR2 looks to be the most difficult of the bunch, with Freelancer winning in the style category. Sar2 can be picked up here.
Qbasic Review News
The Qbasic Internet Age
Want to know more about voxels? Check out the newest part of that series down below...
prt demo?, More Footie, Bubble Fighters, and more
Latest Game updates:
Last minute news came in about Dark Ages 2. Firstly, a couple-hour demo with story, battles, the works, plus Gavan's great art, could be here within the month! DA2 progress is flying along with Finals over for most of the crew, and one 96tile by 96tile map is already done, an area larger than the entire DA1 game! And the plan is for up to 100 maps!
Pyrus, coder of Simpire, among others, has joined the all-star cast of DA2 to help work on the battles. Hopefully his asm handiness and sense of design will help speed up this great game. On top of that, a Dark Ages 3 to begin "after a sabbatical" has been all but confirmed to us by Mike Hoopman, and there is great hope that the entire game can be finished by the end of the summer! Also of interesting note is the Unofficial Dark Ages Homepage, a great site entirely devoted to Dark Ages!
JP Zorilla is working on a new title by the name of Football '99. Presumably his answer to Pasco's France Soccer, this title has some fairly smooth animation in the graphics, and is looking almost as good as Pasco's title. More on the gameplay should be coming soon.
qb:tm was recently shown a new screenshot from Bubble Fighters, Enigma's fighting game, and to say it looked nice was an understatement. Although it was only the 3d arena, the poly count was fairly high for a qb game (it seemed about 50 poly's or more just in the background), and, with the asm in the title and DirectQB under the hood, this title is sure to challenge XENO for the best 3d engine in qbasic.
Speakin' about Pasco's Soccer, there has been a lot of speculation as to the fate of that title recently. Says the man himself, the movement is now fully rotational instead of characters only being able to go left, right, up, and down. However, this has meant the entire AI module has had to be recoded, significantly slowing down production. Groov Buggies 2, a title that was announced way back, has had some work recently, with some "neato special effects"; technical difficulties with the speed of the texture-mapper have slowed work on this too. However, expect to see a few new demos of Freelancer in the near future.
Last of the Legends, Magik's RPG, went into beta this past month, and should go to a final release very soon. As the first full RPG since Dark Ages, no doubt anticipation will continue to drum up for this game as it nears release.
Now this month's shorts: The game which was being called "The Brain's Side Scroller" has been confirmed as Peanut Patrol 2, as we'd speculated last month. With NutzBoy and The_brain, both with projects already behind them, working on the title, it's sure to be good...Mandrake's new game AnnWynnNnn had a screenshot posted of it recently, and it's looking above-average in the graphics department; hopefully the story will be to boot...Jaws-V's partner Change-V, with games such as Cookie Delivery, MiniRPG, and more to his credit, has posted news on his website about a new side-scrolling shooter. Check it out for yourself here
That's all the latest news for this month. Remember, if you have any news or rumours, send them along to Qbasic: The Magazine
Here's what you had to say about last month. Be sure and send us more letters soon!
Attack of the virii? Nice little article.
BTW, NetBus isn't a "virus"...it's a RAT (remote access trojan). And I, I mean we, have been spreading more than just NetBus. Since I program in more than just QB, I had the luxury of making my own RATs, some that aren't as f***ing obvious as "patch.exe", but still have a tendency to get into the Windoze registry and disguise themselves as system philes (sic).
And what's running a RAT through an anti-virus tool going to do? You'll get an "okay" message. Mine go undetected, mabe 'cause Mc"@$$hole" and Norton haven't seen mine.
I usually don't put the email address on a letter, but I figured it'd be fun here. Heh, admit it, this guy is asking for it ^_^.
First of all, what's the correct capitalization of your name? zkman or Zkman or ZKman...?
whatever makes you guys happy, chicos. Never really thought of that, but I usually use....umm...all three! yeah!
A couple of points to ponder...
1) I live in Kyrgyzstan, so add me to the list!
2) I hate French and anyone that types it all over online magazines. I despise Spanish also.
3)LTP: BASIC, believe it or not, is Interplay's fourth most popular software title at this moment in time. Baldur's Gate is second, some Redneck Rampage game is first, and LTPB is third. No numbers were given, just a list.
4) According to Roald Dahl, the BFG spells scrumpdiddlyumptious like that, not scrumm-didlyumptious.
5) The title picture didn't load for me this issue.
P.S. What are you going to do without the monthly asm tutorials? They took up half of it!
You've got comments, we've got answers!
1) ^_^. Read last month's Letter from the Editor if you have no idea what he's talking about
2) No te gusta espanol y frances? Por que no? heheh
3) Also, believe it or not, Interplay lost $25 million in Spring '98, says Next Generation.
4) Close Enough =)
5) Eek! It's fixed now...
And about Petter's articles, they were about 4 pages out of an average 48 page issue, so we're still staying about the same size.
Killerz...umm...don't see what all the fuss is about.
Looks too grainy, things clash, like someone slapped hand-drawn sprites onto a blurry photograph. Things don't mix. I just think it looks a bit bland at this stage. Whatever, heh. If Nek makes the energy bars cooler looking, maybe do hand-drawn bg's that mix, the game could rule.
[crawls under floorboards, back when he came]
Looked pretty cool to me. Wasn't Mortal Kombat also sprites on a blurry background? Oh yeah, Mortal Kombat sucked. =)
I always thought the Qbasic world was a good, clean, bunch of programmers. UNTIL I read the last issue of QB:tm. I am shocked at lost sock's game (to say the least). I mean, isn't there enough crud and junk in the game world that he has to create some in the qbasic world. A fighting game is fine, his graphics look really good quality EXCEPT the content of the game. To sum the whole thing up: that game isn't worth the memory it uses. It's a stain and a scar on the Qb world. And I almost wish we could disown it as a Qbasic game!
Uf! The Killerz backlash is hitting hard this month. Of course, nekrophidius is never one to change the style of his game based on what others say. Perhaps nek would comment?
My first experience with voxels must have been in watching Future Crew's awesome demo "Second Reality" back when I was in high school. It had a dynamic sinusoidal heightfield that the camera panned around in. I was so impressed with the fluidity of the voxels, that I downloaded some more demos and found even cooler landscape voxels
So I went ahead and wrote my first landscape voxel renderer. It looked pretty good, but I had the screen centering code before the perspective transformation done incorrectly, so my voxels were skewed into a circular shape. Nonetheless, it was a successful attempt, and it motivated me to pursue my voxel research even further.
I pored over every 3D tutorial, article and source code I could get my hands on, to increase my knowledge of this new world of 3d voxel-based rendering. I was at first baffled at how voxels could be rendered in only 4 lines of C code in the inner loop, but later understood how all those precalculated tables containg the critical data to determine the projected height of each voxel at each scanline of the screen. From that knowledge, I made a voxel demo (with source) that you can download here.
It's not fancy, but is shows how it can work. It uses a "real" perspective transformation to project the voxels to the screen, so they will not look like tiles.
I'm glad that Alias has decided to write a voxel tutorial for Qb: the magazine. Maybe you too will become interested in voxels, and seek tutelage on how to speedily render complicated 3D objects using such techniques as raycasting, voxel sprites, and octree traversal. If you need help on that stuff, email me and I'll help you out. Good luck!
I don't care if you think this guy is bragging, Toshi is the man. His programs rule. Download that voxel program. Now.
I would just like to know if it would be possible to get a screenshot of the game another DEP member and I are working on into the next qb:tm. Of course, we don't have them ready yet, because i am waiting for some of the GFX to be made, but soon as that happens, I will take screenshots and send them over, if that is okay with you.
A lot of people send me similar stuff, usually about being in the gallery. Although I might not have heard of your game, if it rules, I probably have. So DON'T send screenshots, and send a note like Yoda here if you want to (or, even better, a url).
And speaking of Yoda, I was only in line for an hour to get my Star Wars tickets. Some people I know camped out for 5 days, so I don't feel THAT bad =).
qbasic: the magazine reserves the right to edit any letter recieved for purposes of clarity and space. But you already knew that.
Here's the results of the Issue 7 survey from Qbasic: The Magazine! We need more people to Vote! So do it!
Favourite Game | Last Month | Change 1. Wetspot 2 1 <> 2. Dark Ages 2(t) <> 3. Mono. Shooter (t) 2(t) D1 3. Groov Buggies (t) -- -- 3. Of Hell and Magic (t) 2(t) D1 3. Agent Squeak (t) -- -- Comments: Some variety on Best Game this month, with Agent Squeak and Oham on the list for the first time ever. Favourite Utility | Last Month | Change 1. DirectQB 1 <> 2. QMIDI 2 <> 3. GIF2BSV (t) -- -- 3. SvgaLib 3(t) <> Comments: DirectQB dominates the voting, and PP256 and Spriteshop fail to crack the top 4. Speaking of which, Dash is off the list for the 3rd month in a row. Best Upcoming | Last Month | Change 1. Dark Ages 2 1 <> 1. Last...Legends 2 U1 3. "Project RT" (t) -- -- 3. Eternal Frost (t) -- -- 3. Dash2 (t) -- -- 3. Xeno (t) 3(t) <> 3. FoX (t) -- -- 3. Future Library (t) -- -- Comments: Project RT rejoins the Best Upcoming list. The large amount of promising titles coming soon has led to a variety of titles on the Best Upcoming this month.
Vote today by emailing your votes for:
You need this stuff!
Must Downloads returns for another showing. Two new games were added
this month! Firstly, QBTetris, and excellent puzzler, and SpaceWar, the current
king of the space shooter crop. Everyone knows that
there are a god-awful amount of qb games out there, but what's worth downloading?
These, my friend. Here, you'll find a list of the best of the best in QB progs. See
something that should be here? Tell us and we'll check it out. You HAVE to have this
Bill McDonald's space shooter featuring excellent sound and explosions, along with some fair, 1980's style gameplay.
Lianne...in the Dark Crown
Wetspot & Wetspot 2
Uniqueness is what we use to determine who gets the Site of the Month. If a page has a ton of links, or a program library with no original stuff, it won't be here. qb45.com (Future Software) is not that place.
The creator of the QFinder (basically a qbasic search utility), and home of the best site reviews in the qbasic world, along with some original programs, and a good interface, qb45.com is our Issue 10 Site of the Month.
We like uniqueness
Some amazing isometric tilework and voxel characters set Vampira away from the pack this month!
Alright, has everyone here heard of a landscape engine? No?!?! Well, we'll see about that!
Last issue we covered voxels, which are 3D versions of pixels, and can be used to create stunningly high-detail sprites without too much overhead or loss of speed. As nice as they are, they are not as fast as they could be if we remove some abstraction.
The voxel model we presented last time was an incredibly general model - too general for a lot of purposes, in fact. If you're making, say, a flight sim, or a game like Delta Force, you want to have a big, broad voxel map the size of Rhode Island, but you don't have that much memory. The ability to have true-3D voxels is useless, so if we could just find a way to do a height-map, we could completely forget our previous method and have whatever kind of terrain we want.
Wait a minute! We CAN do a height map! Look at programs like 3D-Lands and the voxel.bas. They are prime examples of simple height maps at work. Since there are so many programs like that out there, I will not bother to write one. Have a look at them and see what you think. Keep in mind that there are many different kinds of landscape voxels. I will go through a simple list and description of the most prominent kinds:
Check out this 3d landscape!
Phew! that's a lot to cover. I know I said I would cover list voxels this time, but I have been awfully busy, and have not been able to prepare. As for the DQB version of the voxel editor, I won't be doing it. All of the mail I recieved about it said that I should not port it to directQB, and since there is no demand for it, I will just let it stay the way it is. See you next time, with list voxels, and finally, in the fourth installment, isometric projection!
Download the voxel landscape generator
Welcome to the Power Programming series
All right, you know about GET and PUT. Maybe even made a few games with them. And with the introduction of such libraries as Blast!, Dash, and DirectQB, you have powerful graphics routines at your disposal.
But, nobody has really addressed the issue of managing all those tiles and sprites you have. Well, fortunately for you, I wrote this article just for that! In this article, you'll learn how to calculate array sizes for your sprites explanations included so you don't have to memorize stupid formulas that don't help at all. You'll also learn how to store multiple sprites in an arrayand how to use two-dimensional arrays for all your same-sized tiles. You'll also know how to save all your sprites into files and simply load them up straight into your PUT arrays! No more hacks of drawing your sprites at the start of your program.
This will be a first in an informal series of articles that deal with power programming.
ArraySize = (Width * Height + 4) / 2 - 1
But what does it all mean? Well, let's suppose that we have a 16x16 tree sprite to GET to an array. Since we're in Screen 13, each pixel is a byte in size (can take any of the 256 possible colors). So, we would need 16 * 16 = 256 bytes to store the image alone. But because GET needs space to store the sprite's width and height, each of which, being WORD values, occupy two bytes, we need an additional 4 bytes for a total of 256 + 4 = 260 bytes. That's what the plus 4 in the formula means.
If we are dimensioning an INTEGER array (where each element is two bytes in size), we would need an array with 130 elements (260 / 2 = 130), hence the divide by 2 in the formula. Here's the code to dimension the tree sprite array:
We used 129 in the DIM statement bacause there is already an element 0 (the reason why we're subtracting 1 in the formula).
If the sprite's size in bytes were an odd value, we round up. For example, if we have a 15x15 sprite, the sprite would occupy 15 * 15 + 4 = 229 bytes which will occupy 229 / 2 = 114.5 or 115 INTEGER array elements. Thus, we dimension the array this way:
Storing Multiple Sprites In An Array
The coder is obviously using one array per sprite. It would be better to store everything in as few arrays as possible so that everything would become clearer. Besides, this is especially suited for tile engines where each tile is the same size. This is also done so that we can store numerous sprites in one file using BSAVE and BLOAD.
The solution lies in the GET syntax. We can indicate in which element of the array to start storing the sprite by simply adding subscripts to the array name. For instance this code actually stores the sprite in the first element, 0.
GET (0, 0)-(15, 15), Tree
So it is the same thing as writing
GET (0, 0)-(15, 15), Tree(0)
If we dimension an array to have 260 elements (520 bytes), we can store two 16x16 sprites in it!
You'll notice that we stored the second sprite starting in element 130 since the first sprite already occupies elements 0 to 129 (130 elements, 260 bytes). The second sprite would then occupy elements 130 to 259.
You can extend this concept to store as many sprites as you want in one array. However, the array cannot exceed 64K in size (good for 252 16x16 sprites) unless you use the /AH switch in QB4.5 and the $DYNAMIC metacommand. Also, be careful that you don't overlap sprites in the array. You can leave gaps, but never overlap them.
An Application: Tile Engine Drawing Routine
For example, we have a Map() array that contains the tile numbers of each part of the map:
So if Map(13, 14) contains a 4, then there's a rock at that position.
If we organize the sprite array so that the first tile is grass, the second tile is a tree, etc., we can simplify drawing the tiles: (Assume that we have 16x16 tiles)
' Draw a 10x10 portion of the map
' Calculate where the tile is stored
' Draw the tile on the screen
' Calculate where the tile is stored
' Draw the tile on the screen
It's very simple, isn't it?
If we're going to use two-dimensional arrays, accessing the tiles will become much, much easier. How do we do it? Instead of dimensioning a one-dimensional array, use a two-dimensional array where the size of the first dimension is the size of the sprite and the second dimension is the number of tiles. For example,
DIM Tiles(129, 19)
This statement will dimension an array that can hold 20 16x16 sprites (figure out why). To store the sprites, just use this
GET (...), Tiles(0, TileNumber)
where TileNumber is the number of the tile you're GETting. PUTing them works the same way.
This method of using two-dimensional array works because the first dimension elements, (0, x), (1, x), (2, x), etc., are contiguous in memory (i.e., they are next to each other).
THE GET FORMAT
Offset Length Description (bytes) (bytes) ------- ------- ------------------ 00 02 WORD width in bits 02 02 WORD height in pixels 04 XX sprite image dataThe sprite data is arranged much like what you would expect. The pixels representing the top row in the sprite are first, followed by the pixels in the next row and so forth, down to the bottom row. Knowing the GET format is essential if you're planning on making your own sprite routines which are compatible to BASIC's GET and PUT routines.
BSAVE AND BLOAD
BSAVE and BLOAD are two memory statements whose purpose is to transfer data between RAM and files. BSAVE lets you store parts of the memory to a file and BLOAD gets from the file and dumps it to the memory. To be able to fully use these commands, you first need to know all about Segments and Offsets, so if you don't know anything about these terms, don't read on until you do. (See the first part of Petter's ASM article in issue 4 for a nice introduction to Segments and Offsets)
filespec Filename (path optional) of the file to save to
or load from.
An example, to quickly save the screen (in SCREEN 13) to a file, you can use the code below. When you run the code, you will now have a file, SCREEN.GFX, in the default directory containing the memory image of the screen. (The palette is not saved, BTW.)
DEF SEG = &HA000
The Screen 13 pixels are stored in memory at the address A000:0000 and is 64000 bytes long (320 * 200 = 64000). The segment A000 is a hex value and thus, the value in the DEF SEG statement contains a prefix (&H) to indicate that it is in hexadecimal. DEF SEG is a command that changes the default data segment for use with such commands as PEEK, POKE, BSAVE, BLOAD, and CALL ABSOLUTE. It has this syntax:
DEF SEG [=segment]
It is usually a good idea to restore the original default segment by executing another DEF SEG without attributes. You can omit this if you know what you are doing.
There is a quirk with BSAVE that you should know. If you specify a file without an extension, BASIC automatically assumes a .BAS extension, which I would say is fairly stupid. Also, the if the file you specify in BSAVE exists, it is completely replaced, so beware!
To load the screen back use this code:
DEF SEG = &HA000
If you omit the offset in the BLOAD statement, BASIC will assume the segment and offset you got the image from (with BSAVE). Omitting the offset is not recommended unless the location will not change. Since the video RAM is more or less fixed in location (it has to be), you can simply use this statement instead of the code above:
VARSEG And VARPTR
Number% = 10
The example above stores the contents of the variable, Number%, into the file NUMBER.TMP.
You can specify any variable as the variablename. This includes array elements and record names. Some more examples using VARSEG:
DIM Map(1 to 10, 1 to 10)
' Get the segment of the first element of Map
' Get the segment of the (3,4) element of Map
DIM Palette(255) as RGB
' Get the segment of the red attribute of color 100
' Get the segment of the first element of Map
' Get the segment of the (3,4) element of Map
DIM Palette(255) as RGB
' Get the segment of the red attribute of color 100
Since many variables change locations often, it is recommended that you use the values returned by VARSEG and VARPTR immediately.
Note: If you want to get the offset of a dynamic-length string variable, use SADD instead of VARPTR since using VARPTR returns the offset of the string's descriptor, not the string itself.
Saving Those Sprites
DIM Tiles(129, 19)
DIM Tiles(129, 19)
You'll notice that we specified the offset in the BLOAD statement since it is not guaranteed that the array will be in the exact same location it was when we saved it.
The BSAVE File Format
BSAVE FILE HEADER Offset Length Description (bytes) (bytes) ------- ------- ------------------- 00 01 BYTE Special BSAVE value 01 02 WORD Original segment 03 02 WORD Original offset 05 02 WORD Length of memory imageThe original segment:offset is the memory address the memory image was taken from. Immediately after the header comes the memory image.
| ||SpaceWar, by Bill McDonald, was released relatively unknown just a few months ago, but in that time has jumped in popularity to a possible Bronze medal in the Qlympics, beating out high-class contenders like SFB2 and Super Mario World Clone. Does this space shooter, the first of a new crop this year that includes Freelancer and Space-a-Roo2, have what it takes to be a Qbasic classic? Maybe.||
The first of the new space shooter crop
First, the positives: This game uses sound better than nearly any qbasic in recent
memory, with some nicely looping BWSB music pumping your adrenaline in the background,
simple voice-overs like "Wave One" or "Game Over" at said points throughout the game.
The problem sound-wise lies in the variety, or lack thereof. As far as I could percieve,
there is only 1 .mod in the entire game! Whereas AAA titles such as Wetspot 2 had new music
for every set of levels.
Another one of the winning points of this game is the explosions. They look, to put it simply, fabulous, up to the level of professional games. It's fairly obvious the explosions are a canned series of animation and not generated real-time a la Marko Dokic' routines, so they might get old after a while, but they do look good when you're flying around.
This game is also virtually bug-free, with zero slowdown, or graphical anomalies. It also is complete, if a little short (we'll touch on that a bit later).
Spaceship go boom-boom, Mommy!
However, there are some downsides to the game. As far as enemies and weapons go, this game doesn't have it going on. You'd expect a space shooter to have multiple weapons on each side (enemy and you), but this game has very few. The harder enemies are generally just harder to kill and faster shooting versions of the same enemies you'd already seen. There are no huge bosses like in G-Darius, or special weapons or anything of the sort.
Also, enemy AI leaves a LOT to be improved. Whereas even early demos of Freelancer had enemy formations like V-Wing and similar, this game's "AI" seems to be random movements to side and up/down. It not only makes the spaceships seem to fly in a "jerky" kind of manner, it also lessens the excitement.
In the graphics department, it's a mixed bag. The explosions, as I've said before, are great, but the rest is not so. Firstly is the heavy reliance of DirectQB tricks that end up not looking very good. The logo at the start does a horizontal scroll of itself, which looks sorta wierd, and various other menus sort of "scroll away" in various directions when you're through with them. Although it doesn't look bad, there have been much better examples such as fading done before. Also, the font choice for areas such as the Storyline is heavily blurred and is almost as unreadable as the font from Wrath of Sona's opening.
Our recommended specs:
100mhz processor, DirectQB, Open EMS
A more difficult enemy
The ships and enemy ships are above-average, although not in the same league as some of the more graphically advanced games of late, such as Freelancer, Dark Ages 2, or even Wetspot 2. They have only one frame of animation, and no little "extra touches" such as smoke carrading off the side of the ship if it's hit, or rockets manuevering you around. The background is also simply space, which, although well done for space, is not the most interesting backdrop for your fighting.
Don't get me wrong, this game is currently the top of the crop for space shooters, providing some decent gameplay, even if there are only 12 short levels of it that are not extraordinarly difficult. But it is simply lightyears behind SaR2 and Freelancer on all counts. Both of those games look and play better even at this early stage than SpaceWar. Maybe 2 years ago, this would've gotten the Qb:tm Seal, but today, with no defining hook, it is merely average.
CONS: Nothing original, ho-hum gameplay
CONS: Nothing original, ho-hum gameplay
M/K used to be the name as far as qbasic was concerned. Of course, we're talking about the (now defunct) Molnar/Kucalaba Productions, a group run by Luke Molnar and Luke Kucalaba, producers of some of Qb's most fondest memories, and the creators of many concepts still around today.
From the insatibaly violent Bob Sagat Killer 2000 and Fury to the quasi-strategic SubQuest, these 2 are some of qbasic's most prolific creators, back in the day when anything went. Imagine the ruckus if Ambush at South Range had come out today, a game about shooting at school! Utility-wise, these guys also broke new ground. MKJ was a common music format in games back before BWSB and QMIDI were even considered. MK's font routines were among the first to replace the PRINT font. And their games set a precedent for mouse use in qb.
For these reasons, we're proud to induct Luke Molnar and Luke Kucalaba to join DarkDread and Angelo Mottola in the Hall of Fame. The name M/K may not mean quite as much as more recent creators like Dark Knight, VirtuaSoft, and Enhanced, but these guys were among the pioneers, and their legacy will live on.
Does you game art, for lack of better words, suck? Do you have an overwhelming sense of despair because you think you can not draw? If your response to the above questions was yes, no, or what the hell is he talking about, then this tutorial might just be for you. The fact is that you don't need talent when it comes to digital art, because your computer can handle much of the work for you. I myself started out where many of you are, and I now am the artist for Dark Ages II. While I cannot say my art is sublime, it is adequate for game purposes (hey, don't judge my art yet, you haven't seen the top secret new stuff : ) ). Through just a few tricks, you can turn you lame sprites and such into glorious works of art that will make Da Vinci writhe with jealousy in his grave.
Yeah, Baby! The DA2 Artist is here to help ya!
Try to consider rare colors, because you do not want to be stuck with a palette that is not capable of drawing something you need. Think of the colors required to draw snow (white alone will not make very good snow!), or sand (yellow does not work for sand!) for example. Do not waste palette space with useless colors just to fill up the palette; if you have thought of all the colors you need, dedicate another row to more shades of a useful color; example: I use many shades of blue, so I would want to make the first row consist of dark blue to blue, then the second row blue to bright blue. A note you might want to take in order to have a palette filled with distinguishable colors is that the normal intensities of a color are often less easily differentiated by the eye then the lighter and darker shades of a hue; this means that you may want to have more bright and dark shades of a particular hue than you have mid-ranged shades. An adequate example of a hue/intensity based palette structure is the one I use for DA2 (9,1). However, do not make the same mistake of having 32 similar shades of black and white, as this palette does!
Here're the example tiles, chico
I generally use somewhere around the upper right corner for my hot spot; you may also use the same, I will not sue : ) . Also note that my hotspot is located "in front" of the object (this is important not only because you want the visible part (front face) of the object to receive the most light, but it will cast shadows more towards the back, so that the shadows do not fall off the sides of the tile). Parts of your objects that receive the most light from your hotspot will be shaded by lighter colors of your chosen hue, while parts of your object that receive little light will be shaded darkly. Parts where your object completely obstructs the light will be represented by a shadow. This sounds like an incredibly difficult concept, but it really is not; furthermore, your shading does not have to flawlessly follow the physical laws of light; no body will nit-pick (except for me :^) ) if your shading is a bit off.
The first type of shading you will learn is called phong shading; it is simply how a normal, smooth surface is shaded. I usually start by shading the darkest regions of the object first, but you may start with the lightest regions (if you start with the mid sections, you are a freak). A sphere (1,1)-(4,1) is one of the simplest models to shade, so we will use it to start with. First you must draw the basic sillhouete of a sphere: a circle; the color you choose to draw the base circle for does not matter, because you will be shading over it with another color. Find the darkest regions, or lightest spots, if you prefer, and shade them. Then continue onwards by drawing a series of successively brighter/darker crescents, or curved regions, until you have a have a fully shaded sphere; each shaded region should surround the next. Finally you will want to draw the shadow, which is fairly simple. The side of your object that recieves the least light will cast a shadow in its respective direction. Just imagine where on the ground the imaginary rays of light cast by your hotspot cannot strike, the areas where light is blocked by the object.
You may also cast shadows on the object itself (only complex objects would do this), but it is rather difficult and I generally avoid it, although you may wish to impliment such techniques. Note that in phong shading, objects are not really shiny, so you should only use dark to medium shades of your hue, excluding the brighter shades. Not all objects have smooth surfaces; some objects will have flat surfaces, or a combination of the two. A cylinder (1,2)-(4,2), for example, has flat top and bottom surfaces, but its length is completely smooth. Because light is evenly distributed about the length of a cylinder, the shading can be formed by using a series of increasingly bright lines. Flat surfaces are shaded according to which angle the light strikes them at; if a face (flat suface) of an object is perpendicular to the rays of light cast by your hotspot, it is shaded fairly bright; if a surface is very slanted relative to the light, it recieves very little light and is thus shaded darkly. You should first separate the distinct faces of your object with random contrasting colors then shade accordingly. Thus a the side of a cube (1,3)-(4,3) facing the light will be shaded relatively light, and the other faces will be shaded medium or dark intensities, depending on how much light they receive. Flat shaded objects, the majority of the time, are shaded with no more than one color to a face.
Of course, in your game, you will probably be shading more than just primitives (simple objects such as cubes, spheres, and cylinders, to name a few), so you must master the shading of complex, or irregular (1,4)-(4,4), objects. First you must find the "dark spots" on your complex object, the places that receive the least light, then shade those accordingly. Next you shade outwards from those spots, with increasing lighter shades of your chosen hue. Wherever your shading converges (for example, the outwards shadings of two dark spots hit eachother) try to mold the two shading areas smoothly together, much like how two drops of water stick to one another as the distance between them lessens. Et voila (yes, I do speak Francais : 0 ), you have a beautifully shaded blob-thingy.
At this point, you may be asking yourself, why did I not just use a gradient (a flood fill that automatically blends from one color to another in a given direction and form)? Well, first of all, many programs can not perform gradients in eight bit modes (Do not work in 16 or 24 bit mode and try to convert down to 8 bit, I guaranty it WILL LOOK LIKE CRAP!). Secondly, hand shading pixel by pixel is much more versatile, and with practice, will produce far more accurate shading. It may seem tedious at first, but take it from me, it is a skill quickly learned, appreciated, and adapted to.
Geez! Look at these tiles!
Metallic and Chrome
All shiny objects have what is called a highlight, which is in essence a reflection of your hotspot. Where light intensity on your object is highest, a highlight occurs. If you can find a really shiny object near you and there is only one light in your immediate area, you can probably see a shiny spot on the object; this is its highlight. So to shade a metallic sphere (1,5)-(4,5), you could draw a series of concentric circles (circles within circles) that gradually converge around your highlight. All the while, the distance between them should be shrinking, so it appears that the highlight gains in intensity as it is approached. Shiny cylindrical (1,6)-(4,6) objects are simple; where light is intensity is highest on the length, draw a very bright line (the highlight on a cylinder would be a line down the length, because -if you remember- light is evenly distributed on a cylinder's length).
If the top of the cylinder is perpendicular to your light rays, it should also be a very bright shade of the cylinder's hue. The same applies for flat objects (1,7)-(4,7); light is evenly distributed about a given face of the object, so where light strikes a face directly, the whole face is very shiny. As for irregular metallic objects (1,8)-(4,8), they follow the same general shading rules of phong shaded irregular objects, except that the shading regions must be spaced as the ones in the metallic sphere are, and eventually, where all the shading regions converge at their highest intensities, highlights form.
The next type of shading is called chrome shading, or reflective shading. As its name states, it is a type of shading used to depict very shiny, reflective objects such as those composed of polished silver or gold. Chrome shaded objects reflect not only light, but everything around them as well. For this reason, chrome objects are rather difficult to shade, and you may not want to use them often, especially if you have to animate a reflective object. Because we can not render real-time reflections on our two dimensional bitmaps, we must come up with a general scene that will serve as a pseudo-reflection map for our object. The most common way to do this is set up an imaginary plane (infinitely large flat surface) and an imaginary sky for our object to reflect. Any given part of a surface on a chrome shaded object reflects whatever it "sees" that is perpendicular to it. Thus, the bottom half of a sphere would "see" our imaginary plane, and the top half would "see" our imaginary sky.
To make a chrome shaded sphere (5,1)-(8,1), I recommend that you first make a metallic sphere. Then draw in the region where the plane would be reflected (you need not draw in a sky region, as that is represented by the top half automatically). The reflection of the plane will curve with the sphere, ultimately creating a crescent shape at the bottom of the sphere. To distinguish this crescent shape from the top half of the sphere (the "sky" reflection), you must shade it either relatively darker or lighter than the top half; shade this region like you would shade a phong object. For cylindrical objects (5,2)-(8,2), the planar reflection is also curved like the sphere; the two reflection types are virtually the same, unless the cylinder top slightly faces the plane, in which case it must also reflect accordingly. Flat surfaces (5,3)-(8,3) are rather easy to calculate reflections on, because they do not distort the reflection at all. The more downwards-tilted a face of a flat object is, the more of the plane it reflects; it may entirely reflect the plane. If a flat face is perpendicular or tilted upwards from a plane, it will usually reflect nothing. Thus, a reflection on a cube could be represented by simple flat regions being reflected on the appropriate faces of a metallic shaded cube. Irregular chrome objects (5,4)-(8,4) are very difficult to calculate reflections on. You must first shade the chrome object metallic, then find parts of the surface that can "see" the imaginary plane, or are tilted downwards. Then you finish it off by phong shading these regions a contrasting shade.
This concludes the tutorial, but check back next month for more shading techniques, such as bump mapping and pseudo-transparency, as well as entirely new concepts such as tiling and others!
It's the end of the issue as we know it
Next issue is comin' your way on June 19. I'm not really sure what you should expect, but look for another voxel article, mebbe some more physics and art, and lotsa super-secret stuff! And don't forget to read the specials we post in between issues! Also, don't forget to register your QB company with the Visionaries Exchange. Till next time... END