Getting started part 3: Making The Game - Dragon Eggs - Creating the world
OS X: These directions are primarily written from a Windows standpoint with special notes for OS X as needed.
Ok, so now you know how to cut and paste stuff, and you can probably take the Tree World example and add bricks and trees and make a crazy level if you wanted. But now you've graduated to something a little more serious...
Remember that Atari 2600 classic Adventure? Here's a pic to refresh your memory:
Now, the game we'll make will be like that only completely different. We'll let the player control a young and brave adventurer that needs to outsmart a scary dragon and steal his eggs (and possibly the golden chalice) before becoming dinner.
You'll learn how to setup your own world from (near) scratch, get your own art into the engine and learn how scripting, pathfinding, and AI work.
We'll start simple and add features as we go.
A world in 6 minutes. (we'll rest on the 7th)
The first bit we'll do in Windows File Explorer, not from inside the editor.
Find your worlds directory and copy and paste the "RT_EmptySkeleton.novashell" file and rename it "DragonEggs.novashell".
Next, copy and paste the "RT_EmptySkeleton" directory and rename it "DragonEggs".
Windows Tip: You may want to move the files you made to another directory, so you don't accidentally delete them when uninstalling. Or be careful to say "no" when the uninstaller asks if it should delete all "worlds".
Tip: I start all my worlds with RT_ for Robinson Technologies, you shouldn't add the RT_ part to your own stuff!
Now, edit the DragonEggs.novashell file with your favorite text editor. (Notepad works fine.)
Find the line:
world_name|Example - Empty Skeleton - Has a title screen and not much else.
And change it to:
world_name|Dragon Eggs. An epic quest awaits!
Save the file. Run your world! You can choose it from the list by running Novashell, or just double click the DragonEggs.novashell file to start it directly.
You should see an incredibly boring title screen something like this:
If you examine DragonEggs/maps, you'll see two maps already exist - Intro and Main.
If you look at DragonEggs/script/game_start.lua, you'll see a line "RunScript("script/intro/intro_menu.lua");", this actually runs a pre-canned script found in base/script/intro/intro_menu.lua which, if you looked at it, would see it loads a map by named called "Intro" and responds to mouse clicks by checking the entity that was clicked for the names "New", "Continue" and "Edit". Any entity clicked is given default collision information (the size of the pic) and allowed to fall.
All of this can be overridden, the file systems are "mounted" in order and the last mounted one (which would be DragonEggs) is checked before the others. (Others just being "base" in this case, which is always mounted first.)
If none of that made sense, don't worry about it, we'll have a formal introduction to lua scripting soon enough, just ignore it for now and realize that none of this stuff is "hardcoded", it's just default scripts.
Enter your world!
Click "Play", you know you want to.
Uh oh, you'll see this. Don't worry, this is normal. The generic intro menu script attempts to locate an entity named "Player" and move the camera to his position and map when New or Continue is clicked. We don't have one, so it will just load the "Main" map and call it a day instead.
Click Ok and then restart the mod with Ctrl-Shift-R.
First, lets jazz up the title screen with our own title.
Press F1. This toggles the edit mode and is actually the same thing as clicking the "Edit" button on the title screen. Make sure you have NOT clicked new or continue yet.
Tip: In case you're wondering, yes, the editor and other debug stuff can be disabled later so you can distribute your game without people screwing stuff up. (Adding the -retail flag is one way to do this)
You'll see the "Editing ** MASTER MAP FILES **, be careful!". Unlike the last tutorial, this is what you want, because we want to change actual world, not just active games.
Wow that's some really horrible mouse-writing on that pic. I'd go get my pen tablet but it'd probably just look worse.
Setting the default world
Since you'll likely be working on this world a while, now is a good time to show you how to set it to load up by default.
Bring up the editor and choose Options->Novashell System Properties. Double click the command_line_parms key and enter DragonEggs.novashell. If it's located in a different directory than the other worlds, you'll also need to enter its path first.
While you're at it, you might want to set "start_in_windowed_mode" to yes or change the default screen resolution.
Grabbing a text object from the System Palette
Look at the map switcher. As always, there is the ubiquitous "maps/System Palette". Click it or press Ctrl-3 to activate it. (because it's the third map down the list)
Click the "text" entity and hit Ctrl-C to put it in the copy buffer.
Next switch back to the Intro menu (well, it's really just a map) and paste it somewhere good.
Unless your game is called "Text" this isn't very helpful. Open the text entity properties and change the following custom data:
Tip: To modify a property, double click it.
- color: set to "0 100 255 255" - This color format is Red Green Blue Alpha. 0 is none, 255 is max. 0 alpha would mean fully transparent.
- scale: set to "5 5" - This means 5X horizontal and 5X vertical. To make it half size, we would use "0.5 0.5".
- text: set to "Dragon Eggs "
It should look like above. Uh, except instead of MyWorld it should say Dragon Eggs. Yes, I'm too lazy to take another screenshot.
Tip: Press TAB to hide the editor windows if they are obscuring when you want to see.
Ignore the normal Base Color and Scale X/Y entity settings when using this, text isn't affected by the base color, and the script is handling the scaling itself.
Now, before you do anything, you need to manually save this, as mentioned in part 2, the map properties for this don't have "Auto Save" check marked, so you have to do it manually. This is kind of a special case for the Intro map, because a player profile isn't active yet and we don't want to save the map because in the process of selecting things, we make the buttons fall and generally ruin the map.
If you've played with the zoom or position you should use Utilities->Reset Camera Position or move it to where it looks best before saving.Use File->Save Active Map Now, or use the shortcut, Ctrl-S.
Tip: In the editor, notice that to click on one of the menu buttons you must click on a place that ISN'T transparent.
Now press F1 and enjoy your handy work. Hmm, what we've learned is bitmap fonts scaled huge look really blocky. A title like this should probably just be done in photoshop and imported like the buttons were.
Speaking of importing pics, it's very easy, let's do that next.
There are two ways of bringing art into the game - the easiest is in the way of "Tile Pics". The important thing to realize about this method is each "tile pic" image must have a unique filename. You can't have two "grass.png" files in different map directories.
Tip: If later, you change grass.png to grass.jpg, the engine doesn't care and existing maps that used grass.png will still work.
Pictures are scanned from all map directories; the engine doesn't care which one it's found in. You can move them around later without any problem.
Engine Tech Tip: In most game engines, tiles store an ID# to reference a predefined image, this is limited and causes problems when merging maps. Instead, in Novashell, each tile stores a hash built from the filename and a rectangle of which part to use. A tile contains all information to display the image independently, without wasting space storing the filename.
Tip: If two images exist with the same name, an error will pop up to let you know.
Novashell can load the following formats: png, jpg, bmp, tga, pcx
Transparent key color as well as full alpha for png and tga formats is supported.
Internally, textures must be a power of two. 128X256 is better than 129X257, because that will get put on a 256X512 sized texture in video memory. Not a huge deal, but it does waste some memory so it's best to keep that in mind when designing your art.
We'll put all our sprites on a single image and then "cut them out" inside of Novashell, two different ways.
Download this image and place it in your DragonEggs/maps/Main directory. You could also create a new map directory and place it there, it doesn't matter at all as far as the engine is concerned, it can still be used on all maps, it's just depends on how you want to organize. However, it must be inside one of the map directories.
Here's what our image looks like. It's enough to make a game. Sort of. The top two things are designed to be 40X40 tiles and the rest will be cut as sprites.
We'll use static pics to get our game going and then later replace the main character with a fully animated version.
About the art:
The tiles, tree and dragon were graciously donated to the game making community by Daniel Cook. The chalice is from Atari 2600 "Adventure" and the "hero" that looks strangely like a cowboy is from another Atari game, 5 points if you know which one.
The stone tile will overlay the brick-road tile and won't be passable.
Note that the image is a .png file with a full 8 bit alpha channel for transparency.
Tip: If a map directory starts with an underscore, it's assumed to only hold artwork and not listed or processed as a map.
Restart your world with Ctrl+Shift+R, this is required each time you add art files as it only scans for art when the world is started.
Click the Edit image from the intro menu, or Press F1 and switch to the Main map, which does the same thing.
Tip: Simply creating a folder in the maps directory and restarting creates a map there. You can also use Utilities->Add New Map.
Tip: All filenames in Novashell are case sensitive. Keep this in mind, if you call your map "Main", from script it must also be called "Main" if you wanted to load it by name. Well, if you want your stuff to run on Linux anyway.
Inside the editor, look for the Tile Edit Floating Palette and choose Utilities->Import Image(s). You should see "my_image" on the list.
Tip: Double click my_image to see its global properties. It's possible to set a transparent key color from this dialog. (Don't set it here though, this image already has an alpha channel)
When you click the image it's placed in the copy buffer. Go ahead and paste it, there's your image!
Now, before closing the Import Image dialog, enable Grid Snap and set it to 40 as the X and Y, which is our tile size.
(This is located on theTile Edit Floating Palette.)
Now paste another copy, next to the first one. You'll notice it was automatically broken up into 40X40 squares where possible. Use Ctrl-G to disable the grid view if that is annoying, it automatically turns this on when grid snap is on.
Tip: No matter how many ways or times you "Import Image", nothing is actually moved or copied, it's just using the same original image we copied there.
Disable grid snap and close the Import Image dialog.
Now, the grid snapped version is useful because the first two art pieces are 40X40 tiles and ready to use. The rest of this paste is fluff, we don't need it. Click and drag to select the parts that aren't the the two 40X40 tiles and erase them.
You should have three tiles total on your screen like the above picture.
Now let's cut out the tree image. Drag a selection box around just the tree part using the left mouse button.
Tip: Hold down Ctrl while dragging to not accidently select or drag-move the tile.
Now, BEFORE you let go of the mouse button and while you can still see the yellow rectangle you're drawing (like in the above pic), press Ctrl-C.
The rectangle will disappear but a new tile will have been created (and put in the copy buffer) that is about the size of the tree. Paste it under the 40X40 tiles like in the pic above. (I've selected all of them so you can clearly see each picture's size.)
Creating tiles from tiles is a quick and easy way to break apart big images into smaller ones when importing with grid snap alone won't cut it.
Use the same method to cut out the dragon, egg, chalice, and hero.
Click on the large tile on the left we've been cutting from and tap delete, you don't need it anymore, and if you do (for instance, because you added new things to it and you want to cut them out) you can just use Image Import to grab the full original again to work from.
Tip: Hold space down while dragging a selection to reposition it. Zoom in and watch the Tile Edit Floating Palette status text to see exactly how big the selection is in pixels for exact cutting.
Building the map
Internally, the engine uses freeform sprite placement for everything, but in many cases it's more useful to emulate conventional tile editing using grid snap.
Enable grid snap at 40 by 40. Copy and paste the brick tile to make a row of tiles. Whee, they line up.
Important: When grid snap is enabled the editor tries to make things 'feel' like a classic tile editor by REPLACING a tile when you paste the same sized tile at the same place on the same layer. This means even though you paste 10 brick tiles on top of each other, only one will be there.
Tip: If you can't see anything after pasting a tile, it might have been pasted UNDER something, if that something is in a higher layer. By default, tiles are imported on the "Entity" layer.
Now, we want to be able to place rocks on TOP of our bricks, so before going any further, let's move all the brick tiles down to the Main layer, so they will be drawn under most things. Select one and hit Ctrl-R to select the rest. Open the tile's properties (Ctrl-E) and click the Main layer, all tiles will be affected.
Warning Tip: When setting properties for multiple tiles at once, only the CHANGED settings are applied. If the layer is already on "Main" and you click "Main", nothing will be changed, there may be tiles in the selection that are not "Main".
To make a nice background of brick tiles first select one tile and put it in the copy buffer with Ctrl-C, then click and drag a selection rectangle out and before letting go of the mouse button, hit F to flood fill the selection with the tile. Don't worry about the exact size, doesn't really matter.
Engine Tip: Novashell uses sector based partitioning and allows extremely large worlds without slowdown.
Handling error messages - the console
If the computer gods have smiled you might not have had a brush with seeing error messages in the console yet.
To illustrate one, I'll delete the my_image.png file from the map directory and restart the world. Something bad has gotta happen! (you don't have to follow along, but it's good to know this)
Hmm, the title screen looks ok. Why don't we click edit and see what happens when the Main map is loaded...
Uh oh. Console output has been super imposed over the screen and there are a ton of error messages in a menacing red color. In fact, you can't even read them all, they've scrolled off the screen.
This message tells us that it expected to find my_image.png located in the "Main" map directory, because that's where it last found it.
Engine Tip: How does the error message know what the file name is if a tile doesn't store the filename? This data is kept in each maps "resources_used.dat" file and it's only purpose is to be available to look up resource hashes to spit out error messages that mean something.
You can toggle the console by pressing the tilde/backwards apostrophe key. (top left key under the Escape key on most windows keyboards) But actually this error won't stop printing because it's encountered every frame. There is a "Utilities->Remove tiles with missing graphics" option but I'll just quit out and put the pic back. No harm no foul.
Introducing our dorky looking hero
First restart the world. If you click new, we'll still get that same "Player" not found thing. Let's fix that.
Switch to the "Main" map and make sure grid snap is off. (we'll have better control this way)
Move the dragon and the "hero" to the middle of the brick tiles. If they appears obscured by brick tiles, check your bricks to make sure they are on layer Main and the dragon and hero are on layer Entity. (I've zoomed way in on the picture above.)
On the Layer Control Dialog, disable the Main layer from the Active For Edit pane so we don't accidentally click those tiles.
Open the hero's properties. We need to set the name to "Player", but it won't let us! Only entities can be named, so click the Convert to entity button. Whee, we can now set it's name to Player.
After converting to an entity a few things have changed. We now have some extra entries in the custom data area. These tell the entity which image to display. Later, after we switch to the entity to use a more powerful VisualProfile, these will be ignored.
The _Density parm controls how "heavy" things are relative to their size when physics are used, we'll get into that later.
Restart the world and choose New. Woohoo, no error! The game starts and the screen is centered on the hero/player. We still can't move or do anything though. To add a brain we're going to have to step into the magical world of scripting...
© Copyright Seth A. Robinson and Robinson Technologies