Community Game: Holy War - Level Designing.

Lend your skills and get involved in a CDN community game!

Moderator: samw3

User avatar
Posts: 1279
Joined: Wed Oct 21, 2009 11:43 pm
Location: Finland

Community Game: Holy War - Level Designing.

Postby bugala » Fri Jun 28, 2013 2:09 am

I am here writing instructions both for my own memory purposes as well as if someone wants to try out level designing already.

These nstructions apply to current build of Community Game, and there is possibility that when we get the stroy in place and graphics, these instructions might change.

First of all, some of the stuff are handled through Tiled:

Here is example of current builds (28 of june) tiled file: ... aptest.tmx
You can see there are 4 layers:

Map - obviosly what map will look like
Creatures - Which makes it possible to put some creatures pre-existing to the level.
New Unit Places - This means the places where you can buy new units at (not implemented yet)
Enemy Unit Approach Tiles - These are the places where enemies can come at.

I will first explain last two, since they are easiest:

New Unit Places - Use only the first tile or no tile at all, by other words, this works on basis of 0 and 1, 0, cant put, 1 can put new unit.

Enemy Unit Approach Tiles - Here you can use as many tiles as you like, each tile represents its own area that you can use (explained later) to put enemies at. Number 1 tile means area 1, number 2 tile, means tile 2. If no tile is put, then enemy cant come from that place.

Map - Here you need to pay attention. Current example is actually quite bad since there are lot of tiles you cant really make apart which is which and theres plenty of those tiles even they are most not in use.

But first of all you can draw the map anyway you like, that is simple as that. But each tile that you use, you need to set up properties for them.

You need to right click on that place where you can choose the tiles, and then choose "tile properties". Currently I have in plans two properties to use.
movement cost and type.

Idea is that with type you can choose for example "forest", and then later I am hoping to implement it so that AI can choose to never go to forest for example. (this "type" property however is not implemented in current version in any way yet).

Movement cost is quite self explanatory, how much movement does it cost to go on one of this type of tiles. If you put cost as 0, it means it is blocked, that you cant get there.

Creatures - Here you can put creatures, each tile represents different creature. In the end I hope there to come pictures of those creatures so you know what you are putting there. Right now i have just been using those different colored tiles for testing purposes, one of the tiles is swordman, one is tisiphone and one is diabolus. In similar way as in map tiles, you right click on that tile piece on that selection screen and choose "tile properties" there you must give some info about each tile. What info you need to write, check from below when I am explaining about attack waves and units.

Attack Waves are currently done manually, and i might keep it that way.

Attack waves are actually tables. like there is lvl1attackwave table.

In Hollywood, tables are created following way: "mytable = {}" I can also add stuff inside "{" and "}".

There can also be many subtables inside tables.

I am giving example code of attackwave to perhaps make it easier to explain what is happening:

Code: Select all

lvl[1].attackwaves = {                    
	    [1] = {
		  [1] = { type="swordman", AI="gotogoal2", goal={x=12, y=2}, group="testgroup2" },
		  [2] = { initializewave="testwave", initializereason="allgoneof", groupstocheck={"testgroup", "testgroup2"} }
	    [3] = {
		  [1] = { type="swordman", comingfrom={2}, AI="gotogoal", goal={x=12, y=2} },
		  [2] = { type="swordman", comingfrom={2}, AI="attacknearest" }
	    [5] = {
		  [1] = { type="swordman", AI="gotogoal2", goal={x=12, y=2} }
           ["testwave"] = { 
		     [1] = {
			  [1] = { type="swordman", AI="gotogoal", goal={x=12, y=2} },
			  [2] = { type="swordman", AI="attacknearest" }
		     [2] = {
			  [1] = { type="swordman", AI="gotogoal", goal={x=12, y=2} }	  

these [number] = {something}
refers to on what turn that something is happening, in this case there are happening on turn 1, 3 and 5

By default there are enemy units coming to battlefield.

Units work following way.

At minimum you need to tell their type, which currently can be swordman or archer (archer not really implemented to do anything else but work just like sowrdman).

If you only tell the type, then engine will automatically fill the rest of the stuff making it automatically level 1 swordman and appearing to one of area 1 approach tiles.

However, you can add more info, and main info you could like to add are:

lvl = (number), to tell which level (for example swordman) unit it is, and then engine will fill the rest according to that level.

comingfrom = {(numbers)} - example: comingfrom = {2, 3} This will tell from which area(s) enemy unit will try to approach from, if you use multiple numbers, then enemy will come from any of those chosen areas by random.
In case you choose 0 as the area, then you will need to add x and y to your unit info, since in this case unit will be put to that exact x/y tile.

Code: Select all

Example: [1] = { type = "Swordman", comingfrom={0}, x=13, y=4 }
this would put level 1 swordman to map tile x13, y4 with default AI.

AI = "name of AI" this will choose which AI this enemy will use, currently following are available: "attacknearest", "gotogoal" and "gotogoal2".

In case of gotogoals, you also need to tell target x/y tile with goal = {x=(number), y=(number)}


Code: Select all

[1] = { type="swordman", AI="attacknearest"},
[2] = { type="archer", AI="gotogoal2", goal={x=4, y=10}  }
This will result in one level 1 swordman that tries to attack the nearest enemy and one archer that is simply running towards tile x4 y10.

here are all the options to put for a unit:

displayname="name" (this the name that is shown to player)
comingfrom={number, number}
x=number (in case put directly on certain tile)
alignment="name" (diabolus or shaddai)
attacktype="name" (hit or ranged)
XP=number (XP character has, this is in case enemies could gain xp and levels in battle, might not happen)
group="name" (which group this unit is attached to if any, this has to do with attackwave purposes)

When making making special unit, you will make its type as the name of the character, as example "captain resistance" similarly if it is supposed to just sat still or have some special AI, then put AI as the name again. In case of special character, you also need to put all the stats to him manually, the movement, HP, MAXHP, all, or it will be missing them.

Notice that when making units (and other commands) it goes the following way:

Code: Select all

[level] = {
   [wavenumber1] = {
                [wavehappening number1] = { happening/unit },
                [wavehappening number2] = { happening/unit },
                [wavehappening number3] = { happening/unit }
   [wavenumber2] = {
                [wavehappening number1] = { happening/unit }
noice also, that when {} is not last one, you need to add "," on end of it. as example notice the above example, wavehappening 1 and 2 have "," in end of them, yet happening 3 doesnt, since it is ending the subtalbe, but wavenumber1 once again has "," on end of it, since next comes "wavenumber2" which again doesnt have "," since its the last wave.

When using tiled to make special character, you put "property name" as the name of the for example "HP", and then value as the number or name, depending upon property.

As example, MAXHP = 100, and type="swordman", these you would put:
Property name: "MAXHP", value: 100
Property name: "type", value: "swordman"

Other wave happening that can happen:

[1] = { text="<-- This is Tisiphone", x=500, y=800}

Puts text to following coordinates ( When we get the real graphics done, I will make this text option more graphical and possibly with more options like possiblity to choose color of text, this is just proof of concept currently)

[2] = { pause=True } - Will wait until left mouse button (or android case tapped) is clicked.

[5] = { removetext = True } - removes all the text currently displayed

[2] = { initializewave="testwave", initializereason="allgoneof", groupstocheck={"testgroup", "testgroup2"} }

Initializewave="wavename to be initialized", in above example you saw there was one of the waves instead of having number [1], it was named as ["testwave"], this was special wave that needs to be initialized first.

If there only reads initializewave="name of wave" and nothing else on that line, then wave will be initialized instantly. However, if there reads initializereason="allgoneof", this means some group must not exist anymore, which groups should not exist anymore, are chosen by groupstocheck={"name of first wave to check", "name of second wave to check"...}

The above example for example means that "testwave" would be initialized at moment there are none of groups "testgroup" or "testgroup2" existing.

Notice that you have to be careful with this one. Since it might happen that your intention is that everyone from group "testgroup" are first killed before "testwave" starts running, but maybe each member of "testgroup" appear only every second turn to the map and it happens that first member for that group is already killed before the next one of the group appears, and in this case when checking if any of that group is still left, program would say that none is left and initialize the "testwave" although it wasnt suppsoed to start yet.

Who is online

Users browsing this forum: No registered users and 1 guest