Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

DarkBASIC Professional Discussion / My RTS tutorial with dbpro

Author
Message
evilsourcil
7
Years of Service
User Offline
Joined: 10th Oct 2016
Location:
Posted: 22nd Oct 2016 17:54 Edited at: 2nd Feb 2017 13:23
Tutorial on games of RTS (real time strategy)
if there are language mistakes in my tutorial, I apologize because I am French and I use google translate tool, it's his fault ^^


This tutorial will not provide complete codes, you may reintroduce into your projects but will rather aim to explain
programming techniques that are in my opinion are essential to the development of an DarkBasic RTS.

But do not you worried I'm planning to leave the base to go to the integration of the network and perhaps the establishment of
The artificial intelligence of the machine.

To convince you, you can download a strategy game I made called "Stratageme"

http://www.sanselme.fr/EvilSourcil/index.php?menu1=Programmes&menu2=DB%20pro&element=Stratageme%20(Real-Time-Strategy)

What? That does not convince you? In this case read this tutorial and do better than me! ^^

PART 1 :: field.

PART 2 :: objects.

PART 3 :: entities.

PART 3 bis :: towers detection

PART 4 ​​:: pathfinding, action list.

PART 5 :: selection of units.

PART 6 :: mini map, fog of war.

PART 7 :: manage two types of random, fighter.

PART 8 :: intelligent network, manage packet loss.

PART 9 :: artificial intelligence.
evilsourcil
7
Years of Service
User Offline
Joined: 10th Oct 2016
Location:
Posted: 22nd Oct 2016 19:25 Edited at: 2nd Feb 2017 13:22
PART 1 :: field.

a ground in db, easy, you tell me.
MAKE MATRIX Matrix
So if the map is made 1000 units wide by 1000 high it makes 2000000 triangle just for the field!
We risk ending up with a fast turn play as a quarter image by second.
But do not worry I propose in this chapter to solve this problem as a point of support for all the rest.
Please note this will definitely be the hardest chapter but you warned.


A / Storage and loading of the ground.

In order to manage the land and these interractions with the game (eg a bump where objects are elevated)
it is essential to store all the informations about it.
For now we will only interest to:
The height of the matrix in these different items
The texture assigned to each point of the matrix (the tiles)
I therefore propose to create two tables that contain these data:



map_width and map_height matches the number of the top of your field in height and width.

Then you can load a field from an external file in our tables.
Unfortunately, how to load a data file if you do not own this file.
I therefore propose to create the data file from your two empty tables.
We can store the data as follows:

a word that contains the width of the map ( in tiles )
a word containing the height of the map ( in tiles )
then for each tiles of your land,
a word corresponding to the tiles associated
a float containing the height of the matrix at this point

I propose a code to help you



Then you can load your file "flat texture map" using the same code as previously but replacing
the write by read, it makes sense, right? ^^


B / Display the field and camera

Okay now, we'll create the matrix !!

That's done...
This is not an error, the matrix is ​​not at all the dimensions of the land contained in the table.
And that's fine because the maps strategy games tend to be very large.

In fact it is just enough that the created matrix fills the visual space of the camera, which is very small when the view is plunging and not too
far from the ground.
A small diagram:





So you will understand that it is difficult (not impossible) to make a camera that moves away from the map or that lifts the view because the dimensions of the matrix must then change.
The dimensions of the matrix that I have given are for a position and an angle precise for the camera that I will give but nothing prevents you choose your own dimensions.

Before continuing I explain the illusion principle of a matrix of the size of the map during a displacement of the camera




In fact the view of the camera shows the entire matrix least one row and one colone.
In this manner during a displacement of the camera, it moves in the space of that line and colone
and when the view moves out the matrix, the camera is repositioned on the opposite edge of the matrix
and all the plots of the matrix are offset (as shown by the small one in the diagram)
Thus the illusion of giant ground is perfect and you can make a map of any size.

How to code this? You can try to do it, I suggest a small code that you can improve.
Make sure that the camera view can't leave the size of the map.





That is pretty daunting. It is crucial to understand this code before continuing.

Before closing chapter, I note, as we have data for only the matrix height peaks and tiles but there may be
many other chart data as the fog of war that can be simulated by the normal matrix.
By being more or less directed towards the camera they can partially or totally obscure portions of the matrices.
evilsourcil
7
Years of Service
User Offline
Joined: 10th Oct 2016
Location:
Posted: 23rd Oct 2016 16:41
I have to go but I would continue this tutorial soon.
For language errors, if someone can correct me, I do not know how it would be good.
evilsourcil
7
Years of Service
User Offline
Joined: 10th Oct 2016
Location:
Posted: 24th Oct 2016 10:51 Edited at: 24th Oct 2016 12:17
PART 2 :: objects.

The objects are all that will be on your matrix.
So the Elements of decor (rock, tree ...) but also units, buildings, or anything.

The principle:
we create a table "object" of the size of the map,
then for each index, (I give an example)

index = 0 if nothing on the box
if the index = 1 presence of a large rock on the box
if the index = 2 presence of a character on the box
... etc

here is for the principle, I think you'll have no trouble integrating the table in the loading map of Part 1.
Then how to exploit?

two nested loops test the tiles visible by the camera (and not all the tiles from the map)
For example if the tile contains a rock (here index = 1)
we will load the model 3d (unless it is already)
and position it.



We must also think about hide unused objects, hence the use of a table "objectnum".

This principle allows for a display and a 3D calculation of what is in the visible area of ​​the camera! (Same as for the matrix)

Note: this code can be improved according to the need, for example if you want to display multiple objects on the same box,
you can make a table instead of a single number by the index table.

In this example, I used a function "get_height #" which gives me the height of the ground for a coordinated x, y
I provided you with function, it helps



Tables of the size of the map can be added if you need more data
example,
a number for a rotation of the rock
or even an offset position of the object if you want to remove the alignment effect

BONUS
you want your object to be oriented perpendicular to the ground to lean on slopes?
As I'm nice, I provided you the function to get both angles to assign to the object

punkyb
7
Years of Service
User Offline
Joined: 8th Sep 2016
Playing: PC and Android Games
Posted: 24th Oct 2016 12:21 Edited at: 24th Oct 2016 12:23
Wow nice work and a tutorial on the side! Thanks for sharing

btw, just checking it now.. why do you have a separate directx version DLL distributed in your game?
evilsourcil
7
Years of Service
User Offline
Joined: 10th Oct 2016
Location:
Posted: 24th Oct 2016 13:00
first to comment !
for the DLL
by testing it on some computer, it was necessary.
I have not investigated why, maybe directx was not installed
Phaelax
DBPro Master
21
Years of Service
User Offline
Joined: 16th Apr 2003
Location: Metropia
Posted: 24th Oct 2016 13:05 Edited at: 24th Oct 2016 13:06
For the ground, you're better off using an object than a matrix. Much better performance plus the use of shaders.

I began writing an RTS tutorial about a decade ago. Has a lot of info in it but never truly finished it. I listed many sources on the thread you might find useful.
https://forum.thegamecreators.com/thread/44248

"I like offending people, because I think people who get offended should be offended." - Linus Torvalds
evilsourcil
7
Years of Service
User Offline
Joined: 10th Oct 2016
Location:
Posted: 24th Oct 2016 13:38 Edited at: 4th Feb 2017 19:08
PART 3 :: entities

Here it is, here we are, managing entities!
It's not just the objects displayed on the map.
Entities can move, breathe, attack, pick up all resources and what we can imagine.

So not surprisingly, it's datas.


A / boot

before the main loop, a first pass will scan the object table to fill our datas and thus identify units
For example, if the index = 2, and that this corresponds to a unit, we enter it into our unit datas tables above.

exemple:


(I joined a camp concept for entities but is not mandatory)

B / management and display

Then, in the main loop
A loop "for" can manage all units
that different from the display that is managed by our system of objects (part 2)

The principle is simple, several tables of the size of the map must be defined
to make a link between the portion of the displayed map and datas entities (the entity number, camp ...)

then if unit number 1 of camp 2 is for example in (5,10)
the path of the display card table give this

number_camp(5,10) = 2
number_entity(5,10) = 1

so you can fetch data from the unit to make its display.
Example,
"Animation_frame (number_camp (5.10)) (number_entity (5.10))"
you can have animation frame, and thus animate your unit
"Position_x#(number_camp (5.10)) (number_entity (5.10))" and "position_y#(number_camp (5.10)) (number_entity (5.10))"
you can move the entity without respecting the boxes ( with floating precision )
Everything is possible

The display and management of the units are separated.
You will understand that no management should be placed in the display section of code
because in this case the unit will be operated only when it is in the field of the camera
ditto for the reverse, run the display unit in managing will slow unnecessarily the program
because this display just will not be visible outside of camera range.

When moving a unit, it returns to the management code to move in the tables "Number_camp" and "Number_entity" one space to another

Last thing, in a game management, units are created and die.
For this, a little trick will keep simplicity and good speed of execution.
For example, a stack listing the empty entity index and another full index
For this, good luck
If not, just find a free spot in the tables.
Ortu
DBPro Master
16
Years of Service
User Offline
Joined: 21st Nov 2007
Location: Austin, TX
Posted: 24th Oct 2016 17:25
Quote: "Last thing, in a game management, units are created and die.
For this, a little trick will keep simplicity and good speed of execution.
For example, a stack listing the empty entity index and another full index
For this, good luck
If not, just find a free spot in the tables"


Matrix 1 free lists are a good way to handle tracking open indices in a custom resource list


A single player RPG featuring a branching, player driven storyline of meaningful choices and multiple endings alongside challenging active combat and intelligent AI.
evilsourcil
7
Years of Service
User Offline
Joined: 10th Oct 2016
Location:
Posted: 25th Oct 2016 09:59 Edited at: 25th Oct 2016 10:12
Quote: "
For the ground, you're better off using an object than a matrix.
"


You're talking about using MemBlocks? if you don't, you didn't read Part 1.

With MemBlocks. we just have to recode two to three field routines.
But I did not want to unnecessarily complicate my tutorial.
evilsourcil
7
Years of Service
User Offline
Joined: 10th Oct 2016
Location:
Posted: 25th Oct 2016 10:16 Edited at: 25th Oct 2016 10:34
PART 3bis :: defense turrets detection area

At this point, you might say: we have the entities,
All towers test the distance with other entities to see if it is close enough to be attacked

So if you have 1000 towers, this is 1000000 tests!
It is therefore a calculation n² complexity, not good for a serious program

The solution is not simple but is worth it.
We create an array of the size of the map in which each element is an array.
When creating a tower or other (units also can attack enemis close if desired)
We add to the table the index number of the tower and this for closes boxes.



This may seem difficult, but with good function it is done.

exemple:
0,0,1,0,0
0,1,1,1,0
1,1,1,1,1
0,1,1,1,0
0,0,1,0,0

Result?
Now it is the management code entities to check if the box where the unit is, is not empty.
If it is not empty, the unit is in the attack zone of one or more defense towers area
and there index are in the table of overflown box.
Thus, the tower will attack it unless it is already attacking another.
This is no longer an algo for each entry in n² who is testing other entities
Now it is the entity that initiates the reaction of the tower (attack)
This is an algorithm of n complexity

ps: In my example, I posted a yellow circle.
Indeed, it is possible that we want to have a distance of attack that does not count in boxes.
One distance test then solve the problem.
evilsourcil
7
Years of Service
User Offline
Joined: 10th Oct 2016
Location:
Posted: 27th Oct 2016 13:59 Edited at: 2nd Feb 2017 13:24
PART 4 ​​:: pathfinding, list action.

For this part, we'll need a table of the map size to report collisions:
0> no collision
1> collision

A / path finder algorithm

The algorithm to find path is interesting.
I'll tell you one that goes with the rts game system,
but be aware that this algorithm is the same as in a GPS except that there is no concept of distance in mine.
This is also the same algorithm for the detection of dead stone in GO
or could work for a zone painting in an image

explanation:
We want for a character to find the shortest way to get from point A to point B avoiding obstacles
And be warned if it is not possible

Imagine that water is poured out where our character is, at point A
Water is spreading everywhere and infiltrates
As soon as the first drop reaches the point B
We find the shortest path by taking the reverse path from B to A and register it
If water has no more plots to infiltrate and point B was never reached, the map collisions prevents the route from A to B

here is the operation graphically:



It is also possible to cut the ground in several plots to speed the search
(Accuracy being less and can cause problems) (that's what I did but I do not recommend it)



ps: before seeking the way with the algorithm, test the straight road is faster
It is also highly recommended to create a border in the collision table:



In this way, there is no testing whether the path finder from an edge (to prevent out of the table)
And the execution of the algorithm will be faster.

The reverse path from the arrival must be stored in a list
I let you find a moving algorithm of your entities that everything happens for the best.

Note that changes to the travel list can easily be made, for example if the entities block
for any reasons:



detect this type of collision is simple and accelerated
by the tables

dim number_camp (map_width, map_height)
dim number_entity (map_width, map_height)

said earlier (Part 3)

A simple test shows whether an entity is on the box, which camp and what is his index.
And without ever testing the list of entities
Quick, simple, and effective

B / list action

When you make an action in your game
Make sure this does not happen
click> causes movement, attack, building ...
but rather
user action is stored with all its necessary parameter and a frame number in a list
then the list is emptied by causing changes in the game with a delay of a number of frame
This part is important because if you create a network among multiple users,
it is sufficient to transmit the action list to the other and that all lists are merged so all network work well.
Ortu
DBPro Master
16
Years of Service
User Offline
Joined: 21st Nov 2007
Location: Austin, TX
Posted: 27th Oct 2016 15:21 Edited at: 27th Oct 2016 15:54
The algorithm is called A* and while you give a decent overview to understand the concept in a general sense, you lack details needed for someone to easily implement it.

Here is a good tutorial that got me up and running a few years ago:

http://www.policyalmanac.org/games/aStarTutorial.htm


A single player RPG featuring a branching, player driven storyline of meaningful choices and multiple endings alongside challenging active combat and intelligent AI.
evilsourcil
7
Years of Service
User Offline
Joined: 10th Oct 2016
Location:
Posted: 27th Oct 2016 16:28 Edited at: 26th Nov 2016 10:08
Thanks Ortu

here are some instructions to help you for the path finder algorithm:

our datas:

dim collision (map_width, map_height)
// 0> no collision
// 1> collision

dim already_visited (map_width, map_height)
// 0> not yet visited box
// 1> the box has already been visited by the algorithm
// You can also initialize already_visited with collision for not testing the two tables at once.


dim way_to_come (map_width, map_height)
// 1-8> the direction from which the box was reached (up, down, left, right, diagonals ...)

dim tag (maximum_number_of_tags) (2)
// Index (0)> x position of the tag
// Index (1)> y position of the tag


Here operations of the algorithm

a small boot by putting in tag (0) the x and y position of departure
then,
we traverse the tags table. For each input:
A:
if the coordinate of the tag is the coordinate of arrival. The path is found, it switches to B
if not, puts one in already_visited at the coordinates of the tag
then adds tags to goshawks boxes blank (collision = 0 and already_visited = 0)
First of
left, top, right, bottom (the order you want) and diagonals
and placing in way_to_come a number corresponding to the direction on the box:
because if the diagonals was added first, the algorithm would zigzag to go straight.
Returns to A except if there is no tag,
if there is no tag, there is no way to reach the finish

B: (if the way was found)
starting from the arrival, then moves to start with the table way_to_come
adding to a list the numbers (those for find the way)



I hope this help will be sufficient for you to write your own function. Good luck
evilsourcil
7
Years of Service
User Offline
Joined: 10th Oct 2016
Location:
Posted: 30th Oct 2016 16:49
1.9 % of american viewers on my youtube playlist of musics !
as those musics are my creations of the moment
come in numerous to see those clip I made, thank you
I would continue the tutorial when I have reinstalled DBPro
Phaelax
DBPro Master
21
Years of Service
User Offline
Joined: 16th Apr 2003
Location: Metropia
Posted: 10th Nov 2016 16:55
I good A* library was already written by IanM.
https://forum.thegamecreators.com/thread/206280

"I like offending people, because I think people who get offended should be offended." - Linus Torvalds
evilsourcil
7
Years of Service
User Offline
Joined: 10th Oct 2016
Location:
Posted: 12th Nov 2016 10:44 Edited at: 2nd Feb 2017 13:25
I do not know for library
But when it comes to an algorithm you can write yourself in few line of code ( See my message above to help )
I prefer to do it myself
and in the case of a rts, the algo must be not only thought to go with the network
But variants of the algo (for example without a specific arrival point)
Will have to be put in place for the reactions of the entities and the AI

Then the simple fact of knowing the functioning of the path finder seems to me a good reason to do it
After I would not say the same thing for example a physical engine
Phaelax
DBPro Master
21
Years of Service
User Offline
Joined: 16th Apr 2003
Location: Metropia
Posted: 14th Nov 2016 23:32
If you're not using a library, implementing a pathfinding algorithm takes more than just a few lines of code.

"I like offending people, because I think people who get offended should be offended." - Linus Torvalds

Login to post a reply

Server time is: 2024-04-18 08:23:56
Your offset time is: 2024-04-18 08:23:56