Trigger combat for RPG game

Blitz3D Forums/Blitz3D Beginners Area/Trigger combat for RPG game

Giuliani(Posted 2013) [#1]
Hi all,
I'm working on a little RPG game and I would like to know how I could proceed to launch randomly (timer) a combat like old school-RPG.
I already have the worldmap and the character and I would like that, randomly, between 30s and 2min, (only if the player is moving) a combat begins, the player is loaded on a new map based on the same "environment" where the player was on the worldmap) (for instance, if the players is crossing a desert, so it loads the combat map "Desert") I'm sorry if I'm not clear ^^

Thanks in advance for your help


Yasha(Posted 2013) [#2]
Are you moving on a tile grid (even an invisible one), or any other system that lets you measure the number of "steps" - not necessarily literal animation steps - the character has taken?

If so, just set a lower bound (you don't want it to be zero or it might get nasty on the player) and an upper bound, so say "between ten and fifty steps", and select a random number within that range on entering a stage or after the last random battle. Set a counter to this, and decrement the counter on each step until (counter - lowerbound) = 0. If you make the upper and lower bounds properties of the current level, you can have more and less aggressive areas.

If you don't have an obvious way to measure steps, that's where the real magic will lie. For a system that allows more or less "analog" movement in any directions, instead of a grid (think FF7-10), you could poll the player position each frame, and consider a "step" to have been taken each time the player has moved more than 1 metre away from their last recorded position (then record the new position and measure from there next frame).


RemiD(Posted 2013) [#3]
Yes i agree with Yasha, counting the number of steps or the total length of movements since the last encounter is probably better for a FF7 random encounter effect, because if you rely on a timer, an encounter may happen even if the player does not move or is away.

Last edited 2013


Kryzon(Posted 2013) [#4]
About the desert: you should know what chipset\tileset the current level is using. Whenever a random fight is to be enacted, query what kind of tile the player is standing on.
If the player is lying on top of a desert-related tile then you can show the desert scene etc.

What you use to find the tile the player is currently stepping on depends on your map configuration. If it's standard square tiles stored in a two-dimensional array:[bbcode]
tileRow% = Int(PlayerY / TileSize)
tileColumn% = Int(PlayerX / TileSize)

Map(tileRow, tileColumn)[/bbcode]If it's a 3D RPG you can get the texture for whatever surface the player is stepping on.


Giuliani(Posted 2013) [#5]
Thanks a lot for your help.

For the "steps", I think I understand, but I thought to something simplier like If keyHit then timer/WaitTimer

I thought to something like that too, by changing of camera.
By searching on this forum, I found this example:

1) The characters stay exactly where they are but are frozen.
2) Their 'combat' counterparts are unfrozen.
3) The opponents are added.
4) The world camera is hidden.
5) The main combat camera is unhidden (I have four cameras for combat).
6) Combat begins

When over:
1) View switches back to world map.
2) Character positions reset
3) Monsters removed.


What do you think about this way to proceed? Isn't it "too heavy"?

I have forgot to precise, this is a 3D RPG.
So it means that I have to check the texture first in the program, and then load the map related to this texture?

Thanks in advance

Last edited 2013

Last edited 2013


_PJ_(Posted 2013) [#6]
I would agree with RemiD or Yasha regarding the use of actual number of "steps" taken, rather than a timer, since this would ensure a reasonable amount of distance is actually travelled between combats.

So it means that I have to check the texture first in the program, and then load the map related to this texture?

The idea of checking the "Tile" was specifically for 2D RPG's (Like the old Zelda/FF style) so for 3D, a direct comparison would be checking the Texture beneath the character's feet (i.e. downwards on the Y axis)
Something like:

LinePick(EntityX(Char,True),EntityY(Char,True)EntityZ(Char,True),0,-1,0,1.0)
Ground=PickedEntity()
Surface=GetSurface(Ground)

Brush=GetSurfaceBrush(Surface)
Texture=GetBrushTexture(Brush)
File$=TextureName(Texture)



However, there may be better ways of doing this, since, presuming you are still working from the World Map idea, you may have split the world map into regions which each have an invisible mesh that can be checked for distance/collision and it is these regional meshes which can determine the type of enemies encountered.




1) The characters stay exactly where they are but are frozen.
2) Their 'combat' counterparts are unfrozen.
3) The opponents are added.
4) The world camera is hidden.
5) The main combat camera is unhidden (I have four cameras for combat).
6) Combat begins

When over:
1) View switches back to world map.
2) Character positions reset
3) Monsters removed.



What do you think about this way to proceed? Isn't it "too heavy"?



This would seem to be a good standard way to proceed generally, sure.


Giuliani(Posted 2013) [#7]
thanks for your precious advices, guys.
And sorry for my misunderstood, english is not my native language ^^

But one thing that I didn't understand with the "number of steps", if I proceed with the frames system, I will have to include the number of frame for the animation "idle" too?
because I would like that the combat begins only and only if the player is walking on the map, if he doesn't walk, so his position is idle, so the combat cannot begins as if the game is in pause.
How can I measure the numbers of steps differently?

For the world I will follow your advice PJ, i will create several mesh for each different region.
Does the LinePick function work at the same for the region mesh?

Thanks again


RemiD(Posted 2013) [#8]

How can I measure the numbers of steps differently?


I see 2 ways of doing this :

1)With number of steps :
If you use 3d animated meshes, you can use these commands to know when the animated mesh put a foot on the ground :
If(AnimSeq(Mesh) = SequenceWalkForward)
 If(AnimTime(Mesh) = 10)
  ;Character has put his left foot on the ground
 Elseif(AnimTime(Mesh) = 20)
  ;Character has put his right foot on the ground
 Endif
Endif


2)With the total length of movements
Simply store a variable where you add all the lengths between the old position and the new position of the player each time the player moves.
For example :
Let say your player can move at a speed of 1m per second when he is walking forward.
Each time you move the player, you add this 1m to a counter and when the counter is equal or superior to a desired value (which can be chosen randomly at the end of each encounter) an encounter happens.

Last edited 2013


Giuliani(Posted 2013) [#9]
I see,
thanks a lot remiD for your help.


Kryzon(Posted 2013) [#10]
I was looking at Chrono Cross, a 3D RPG from Square. They pick a specific battle scene based on the whole level you're in, not the piece of ground you're standing on.

That is, if you're in a desert world, every single fight you have there will take place in a desert-like arena.
If you're in a forest, the arena used is one full of vegetation, trees, grass etc.

It's really easy for the player to immerse, and the arenas don't look bad.
The fighting arenas follow the themes of the whole levels, not the ground textures - so I take it back; you don't really need to fiddle with textures at all.

Reference:




Giuliani(Posted 2013) [#11]
Hi Kryzon, this is exactly what I mean and what I want to do.
But you are only talking about a battle based to a scene, a specific map.
My problem was about the worldmap, when only one player (not the others members or the team) is running on a scaled worldmap. The fact is that this player will cross desert, forest, volcano only in a few minutes, the environnment will be very different.
My best example is the worldmap in Sony's RPG "the Legend of dragoon", this is exactly what I want to do (without the linear path) or peek in Dragon quest's worldmap too

Thanks for your help


Kryzon(Posted 2013) [#12]
This is a screenshot from that Legend of Dragoon world map you're talking about, just to establish some context:



There are various ways to do it without handling textures. For optimization reasons with the PS1 they probably had to texture all that ground in the entire 3D map with a single texture - something you could do as well - and that would render any texture methods not good for this.

• I was thinking you could use polygonal zones that you tag with a battle arena value (plot a polygonal zone enclosing your desert area, tag it with "desert battle arena"), then at the moment a fight is called, test your character's [X,Z] position against all polygons in the world with this code archive entry, and call for the battle arena of the polygon he's currently standing inside.
However, this can lead to empty holes if all the polygonal zones aren't placed in an adjacent manner (easily fixed with an editor you can build, but anyway).

• So an easier - and just as fast - way is to draw a 2D map.
First, choose what RGB colors are associated with what types of arenas (one color to be associated with one type of arena), then paint the zones.
Say your entire 3D world spans 300x200 3D units in the [X,Z] plane; you would then create a 300x200 pixel bitmap in MS-Paint or whatever, and according to the regions in your world (ruins, deserts, forests, secret places), paint appropriate zones.



When the step counter finishes and a battle is to be carried out, ReadPixel the map a single time with the player's rounded coordinates:
ReadPixel(Int(PlayerX), Int(PlayerZ), ImageBuffer(world1_battle_map))
Considering your 3D world having its top-left corner at [0,Y,0].


Giuliani(Posted 2013) [#13]
Waow, Thanks a lot for all these explanations Kryzon.
I don't get everything yet^^ because I need a little more experience and practise with Blitz but I will try to understand and apply your advices. and methods, these systems seem to be perfect for my project.

Thanks again


RemiD(Posted 2013) [#14]

ReadPixel(Int(PlayerX), Int(PlayerZ), ImageBuffer(world1_battle_map))


I have done something similar in the past.
If the bottom left corner is the origine (0X,0Y,0Z), and if each pixel on your image represents one unit, then i suggest :
PX% = floor(PlayerX#)
PY% = ImageHeight%-1 (or MapDepth%-1) - floor(PlayerY#)
ReadPixel or GetColor at PX,PY


Giuliani(Posted 2013) [#15]
Thanks RemiD

Something that I don't understand is that the Pixelmap need t o be apply to the worldmap mesh as a texture, right?
But it should be masked, or place under the terrain texture?


RemiD(Posted 2013) [#16]

Something that I don't understand is that the Pixelmap need t o be apply to the worldmap mesh as a texture, right?


Giuliani>>
You can use a quad to have a flat map as in Legend of Dragoon or you can use a Terrain with reliefs.
On this quad or on this terrain you add a texture with colors, shades, details to make it beautiful, and you use another image with only the colors that represents the differents zones of your map.
For example if the map measures 100units in width and 100units in depth, you can use a texture of 1024*1024pixels to add many colors, shades, details to the map mesh (quad or terain), and also use a 100*100pixels image with the different zones colored with different colors.

Or you can use the same resolution for the texture with colors, shades, details and the image with the colors of the zones because with the code mentionned above you will analyze only one pixel of the image so this will be fast.

What is important is that the width and depth of the map mesh (quad or terrain) corresponds to the width and height of the image. This way you will be able to know precisely the pixel to analyze on the image.


Giuliani(Posted 2013) [#17]
yes I understand

But The image with colors will not be show ingame, so i will need to mask it, right?


Kryzon(Posted 2013) [#18]
You're converting the player's position in the 3D world to 2D coordinates that you use to pick a corresponding pixel in the battle map.

I was thinking the "battle map" as something unrelated to the worldmap mesh. While the world mesh can have any kind of Brushes coloring it (texture layers, blending etc.), the battle map is kept separate.

This battle map is a standard blitz image loaded with LoadImage(), and it's used more like a guide for consulting every time you need to start a battle. So it doesn't need to be "applied" to the world mesh.


RemiD(Posted 2013) [#19]
There is also another way to detect in which zone the player is on the map.

You can use one map mesh (quad or terrain) + one texture for the colors, shades, details for the render.
And several low tris meshes which represent the different zones on the map.
Use NameEntity(Mesh,"Zone"+Str(ZId%)) to set the name of each zone mesh.
Set all these zones meshes to pickable.
Do a linepick from above the feet of Player to below.
Check the picked mesh
Retrieve the Name$ of the picked mesh
Retrieve the Id% of the picked mesh
And you know in which zone the player is.

This should be fast if you use low tris meshes for the zones and if there are not too many zones (to make it faster you can do a preselection by checking which zones are near enough player and set only these zones to pickable)


Giuliani(Posted 2013) [#20]
So if I well understood,

the "battle map" (= the image with colors) won't be applied to the worldmap.
It just a "guide", and I will just convert the player position to 2D coordinates, so that The battle on a specific map could begin.

Thanks again


RemiD(Posted 2013) [#21]
The image with the colors of the zones will be stored in memory, you don't need to show it or to hide it, you only read it when you need.


Giuliani(Posted 2013) [#22]
Ok, I got it ^^

thanks