Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - lafouine88

#41
Wow this seems really cool oO, thanks again
When is AGS 4 update planned for then?  :grin:  :grin:
#42
@Crimson Wizard Overlays indeed look quite promising. Still I can't figure out something. This function simply draws an object/image on the existing room. But it doesn't stretch the room limits. So eventually this comes back to the problem I meant yesterday, if I want a continuous large map, I still need a huge blank map the same size on which I would add the different pieces of map right?
Or do you mean that each time I add an overlay I should 'replace' all my coordinates to get back in the center of my room. A little like a treadmill?
#43
Actually, Using overlays seems very promising and seems doable. I ll give it a try and keep you posted if it's works, or, more likely, if I need help😅😅
#44
Quote from: Crimson Wizard on Fri 19/07/2024 20:54:45The thing is, it does not matter whether there's a valid background, or a blank background, it takes exactly same size in memory ("blank" pixels are still pixels).
I thought the same but was explained that pictures are like divided into areas of the same exact colors. So if you have one huge area of a single color it takes almots no memory (my room sprite was 100 ko) while a picture with different colors on every pixel will take more, even a two colors grid (the map I drew was 18Mo and it's more than 4 times as small). Multiplied by the number of maps I thought it was worth saving a bit, maybe it's not relevant compared to the extra ram it would require to generate the tiles.

To get back to the main issue.. With your explainations, I don't really see how I could work that out. It seems out of my range and maybe should have been planned earlier.

Too bad then, I guess I'll go with the loading pauses. I'll do my best to smooth them out :s

Thanks for all the tips Crimson  :)  :)
#45


Oh yeah I forgot, this also happens (here the background is 6k*15k)

https://ibb.co/N3GPGYW
#46
Quote from: Crimson Wizard on Fri 19/07/2024 09:34:26I think i posted a reply to something very similar a while ago. (I cannot remember whether it was your question or someone elses).

Yes, it was on an optimisation issue I had, and this topic came up^^.
I thought about your reply and I think I understand it. I would totally go for a dynamic sprite generated background map, I guess it would save considerable memory/RAM. But to do that it would be much easier to initally plant a huge room, on which you would define your walkable are mask, characters' positions etc. and then turn the background to a big black sheet, that you would continuously replace with the dynamic sprites as the character moves.
The problem is(and the second part of your reply makes me wonder why :confused: ) I tried to create a big plain room of 6k*10k but when I wanted to draw a walkable area, the program crashed. I thought I had excedeed the limits of ags but maybe that's not it.

I'll try again ^^
#47
Hi guys

I'm facing a room problem on my rpg game. I had planned to design large rooms, like in DIABLO, in which the player can feel the universe IS big. I initially thought this wouldn't be a problem for the AGS engine but after a few tries and discussions on the forum, I realized I was going to be limited by the room size.
I read in a very old post here that the max room size for a 640*400px game ( my resolution) is 2800px height and pretty much unlimited in width. I tried a few things and it is great for 2800*10000(it also works with 2800 width and 10000px height btw).
Thing is, I really had planned a 5600px high map, so I'm missing half of it with this limitation. I tried creating two different maps and setting an edge between them that teleports to the next map with eNextscreentransitioninstant, but there is a tiny pause that also breaks the character walk. The last part can be corrected with a load function I guess, but I couldn't remove the small loading pause, even with a blank room and nothing to load in it.

I guess I could go with it, it breaks a little the dynamic and maniability (which is important in this kind of game) but it's not a huge problem. But before I resort to that I would like to know if any of you already encoutered this kind of issue and if you found a trick :)

Thanks <3
#48
Ok thanks a lot to you guys for all the precisions :cheesy:  :cheesy:  :cheesy:
It s much clearer now
#49
Thanks Khris. Two little questions then :

-With the code optimisation that you propose, I havent' tried it yet but it seems like the data will be updated every second. Problem is, if I cast a spell at 00.00.00.00 and a second different one at 00.00.00.20, the second spell's infos will also be displayed at the exact second(t), which means there will be a small delay with reality, right?

-I'm intrigued by your last sentence, but to be honest I don't really understand "^^ could you please explain to me differently?
Does that mean that the amount of variables I create directly increases the memory consumption,"reserves it", but then no problem with scrolling through them?
If that is the case, is it necessary to lower the variables (global variables, or inside a struct?) to the strict minimum? Because I sure did use a lot and didn't really worry about optimisation on that.

Thanks and sorry for not getting it clearly^^
#50
Hi guys

Just a quick question about the repeatedly execute function. I'm not sure how it actually works and I'm a bit concerned about wasting memory because of lazy coding.

I'm using quite a lot of this technique :

Code: ags
function cd_countdown(int i){
//this function aims at displaying the cooldown of a spell once you've played it. (When you cast the spell,it sets Spell[i].cd to a positive value, which triggers the following codes)

 if(Spell[i].cd>0){
   Spell[i].cd--;
   gSpellbar.Controls[i].AsLabel.Text=String.Format("%d", 1+(Spell[i].cd/40)); //a label from the gui that appears on top,
 }
 else{
   Spell[i].cd=-1;
   gSpellbar.Controls[i].AsLabel.Visible=false;  
 } 
}

//but since there are 10 buttons in my spell bar I want it to be checked for every button and spell so I use this :

function repeatedly_execute(){

for(int j=0;j<10;j++){
cd_countdown(j);
}

}

It works fine, but it looks like a huge waste of memory. I feel like the system is checking every second for every Spell.cd to be positive while I would like it to only activate when it's necessary. Do you know if this is the correct way to put it, or if I should add some more conditions to make it less memory consuming?

Thanks a lot :)
#51
Hi again guys.
Actually, I still have problems with the simplification of my function. The solution I tried and that was corrected by @Snarky doesn't work well :s The info don't show up most of the time. Thought sometimes it does !??
I give you the code I'm using a bit more accurately hoping that someone could find the glitch. I couldn't :/

Code: ags
#define MOUSEOVER_NONE 0
#define MOUSEOVER_TRIGGERED 1
#define MOUSEOVER_HOLDING 2

function Mouse_over(){


  InventoryItem*item=InventoryItem.GetAtScreenXY(mouse.x, mouse.y);
  Character*perso=Character.GetAtScreenXY(mouse.x, mouse.y);
  GUIControl*lab=GUIControl.GetAtScreenXY(mouse.x, mouse.y);
  GUI*gi=GUI.GetAtScreenXY(mouse.x, mouse.y);
  Object *objet=Object.GetAtScreenXY(mouse.x, mouse.y);

if(lab!=null){
  
  if(lab.OwningGUI.ID==54){  ///////specific infos for specific gui54
int s=lab.ID-10;///specific link between my controls numbers and my array
///set the placement and dimensions for the info gui 'ginfoloot'
  gInfoloot.Visible=true;
  gInfoloot.X=41;
gInfoloot.Height=(stuff[s].lignes+5)*10;
  gInfoloot.Width=150;

  Infonom.Text=String.Format("%s",stuff[s].Name); ////this label is part of the info gui

  }
  //-------------------------------------------------------
    else if(lab==Btnbuffennemi1){
//here goes the same kind of infos, but for another type of control
//and so on for all the possible guicontrols
}
}
///------------------------------then we go in case the mouse is over a gui------------------
 if(gi!=null){
if(gi==ginventory){
///for some reason I use another gui to display info here, called 'ginfo_aide'
  ginfo_aide.Visible=true; 
  ginfo_aide.X=49;
  ginfo_aide.Y=329;
  Lblinfotitre.TextColor=65184;
  Lblinfotitre.Text="Backpack (B)"; 
  ginfo_aide.Height=20;
  ginfo_aide.Width=110;
}
else if(gi==gSpellbook){
//same for the other guis
//...
}
}
//-------------------
if(item!=null){
//same for items, characters and objects
}
mo = MOUSEOVER_HOLDING;
}

  void repeatedly_execute() {

    if(InventoryItem.GetAtScreenXY(mouse.x, mouse.y)!=null||Character.GetAtScreenXY(mouse.x, mouse.y)!=null||GUIControl.GetAtScreenXY(mouse.x, mouse.y)!=null||GUI.GetAtScreenXY(mouse.x, mouse.y)!=null||Object.GetAtScreenXY(mouse.x, mouse.y)!=null){
  if(mo==MOUSEOVER_NONE){mo=MOUSEOVER_TRIGGERED;}  
    }
    else{mo=MOUSEOVER_NONE;}

    if(mo==MOUSEOVER_TRIGGERED){
      Mouse_over();
      }
}

It's not the exact code but the structure is here and I couldn't find why this wouldn't work :( seems logic to me '^^
Do you guys have any ideas what could be going wrong? or suggestions for other methods to display my strings without refreshing all the time (see previous posts)

Thanks <3
#53
@Snarky

So, the first part works perfectly (and I discovered the switch tool that I never used before"^^). That adds a lot of code but since it's a separate function it's quite readable.

For the optimisation, I did something quite simple that seems to work and seems logic, but i can't reaaly check if it is more optimized.
I modified like this :

Code: ags
int mo=0;

function mouse_over(){
///the same as before except at the very end...
mo=2;
}

function repeatedly execute(){
if(GUIControl.GetAtScreenXY(mouse.x, mouse.y)!=null){ ///||GUI.Getaatscreen||object... for all the type of objects that trigger mouse_over
mo=1;
}
else{
mo=0;
}


if(mo==1){
mouse_over();
}

}

Does that seem good?
#54
Ok thanks @Snarky. I guess the first option would be the easiest so I'll try and go for this one. I thought about the third option at some point but could not figure out how to make this work "^^, I'll stick to simple then.
Special thanks for the advice about the repeatedly execute string. I didn't really realize how memory consuming this could be, but you're right, it's stupid to keep generating it, I'll add a way to change this only when infos change.

I'll keep you informed, thanks again :)
#55
Hi guys

So here is my new situation...I swear I'm almost done with my game settings so soon there shouldn't be more questions^^hopefully "^^

I'm working on a rpg game. To make things more cumfortable for me I stored all my struct data in one single script. I set a function that I call on game start so all my spells,inventory items etc. are loaded at the beginning.
As so :

Code: ags
#loadscript.asc

function dataload(){
////loads the data for items...
  loot[0].sprite=2184;
  loot[0].Name="Casque rare de la Chouette";
  loot[0].bonus_agi=10;
loot[1].sprite=2185;
//.....

///and also for skills. Like a template that evolves through a skilltree

  skill[1].Nom="Hard skin"; 
  skill[1].Description=String.Format("Increases armor by %d%",(skill[1].lvlcurrent+1)*2);
  skill[1].sprite=403;
//skill[1].lvlcurrent=0;
skill[2].Name="Advanced strenght";
//.....


}


function game_start(){
dataload();
}

It's great for items and spells because there are 'frozen', they don't change with time. But the skilltree part evolves. When you grow to the next level you get a skill point that you can spend in any of those skills.

Then the corresponding int evolves : skill.lvlcurrent++;

And here is the problem. I use a repeatedly execute function to display the current level of progression of the selected spell. As so:

Code: ags

function mouse_over(){
   GUIControl*lab=GUIControl.GetAtScreenXY(mouse.x, mouse.y);
   GUI*gi=GUI.GetAtScreenXY(mouse.x, mouse.y);

 if(lab!=null){ ////there are a bunch of other conditions here but I removed them to stay focused on the issue

  Lblinfotitre.Text=String.Format("%s",skill[u].Nom ); ///this first label gives the skill name. Works perfectly
  Lblinfo.Text=String.Format("%s",skill[u].Description); ////this one calls for the description given before. Here is the problem
}

function repeatedly_execute(){
mouse_over();
}

I hope I'm making things clear enough "^^ basically when you pass the mouse over the buttons that represent each skill, a gui with two labels appears, and the labels change to give the right names and description of each spell. I link a video to show better. What should happen is the description should change from 2% to 4%,6%,8% and 10% with each click.

https://streamable.com/t0k82d

The problem is skill.description stays 'frozen'. I guess it loads at the start but 'prints' the current data to the string, and then doesn't evolve anymore. So if I add points to this skill, the description doesn't change as I would like it to.
I guess one of the solution would be to hard code every description in my mouse_over function but I find this way too heavy, and if there is a clever way to do that I would gladly take it.

Thanks in advance :)



#56
@FortressCaulfield , This would work, it was my last resort solution. But that would mean the covering image would need to be a square as well, to be able to cover the whole thing. I would have prefered a lighter interface.

@Khris This is exactly it!! I really need to understand how dynamic sprites work, this is so powerfull 8-0 .

Thanks a million <3
#57
Hi guys

I'm currently working on a minimap for my RPG game. It was much easier than, I expected. Though, I'm having a display issue.

Basically, I created a gui, in it I put a button with the map picture as background image and another button on top, in the middle with an arrow skin (in 8 directions).
And it goes :

Code: ags
function room_RepExec()
{
 Btnfondminimap.X=64-(player.x/10);   ///map size in 10 times smaller than the original one
 Btnfondminimap.Y=40-(player.y/10);
 Btnarrowminimap.NormalGraphic=3220+player.Loop;  ///3220 is the arrow facing down, then the 7 others follow the standard directions
}

Everything is very promising. Still, I wanted my minimap to be round :s, like in Titan quest or WOW. And I don't know how to "crop" the map button so that it would be a round shape instead of a square one. I'm pretty sure that is not possible like this, but I thought maybe there was a clever way to limit the size of my button to a round 50px radius image.

Any ideas or shall I just go with a square standard minimap?^^

Thanks :)
#58
Thanks Crimson for the fast answer  :smiley:

At first I used properties, too many, and not the right way^^ meanning that for each inventory item I copied every single stat in a single propoerty. This was really tedious and I had the risk to forget one property among all others (but I didn't create a property for the item index to create an easy link"^^). I thought this system was too heavy so I completely went another direction. The one you suggest is clearly the best idea, I feel stupid for not coming up with it on my own^^ it helps a lot to see things from another point of view.


QuoteOverall, when you need to have 2 objects connected, don't do that with iterating arrays, instead create "links" for a faster access.
When possible use integer indexes instead of strings, because comparing strings is slower.
If you really need to use strings, check out "Dictionary", which is made for a faster searches by a string key.
That's copied, I ll be cautious with this :smiley:

QuotePPS. Ah, I should also note that AGS has a limit of 300 inventory items, for some reason. If you think that your game will need more of these, then you would need to think of another solution (reusing InventoryItems for multiple purposes, for example, or else).

This shouldn't be a problem. I am using some kind of conversion item to create inventory items only when necessary, and free them when destroyed. Like so:

Code: ags
  function Materialize_loot(int enemyId) {

      for (int li = 0; li < limitestuff; li++) { 
////I attribute loots at start up using a function given in a previous topic by Khris. But it's just data until triggered by this function.
///"count" is the amount of item[li] character[enemyId] has in its inventory
    int count = enemy_item[EiLookup(enemyId, li)].count;
    if (count > 0) {
      int tt=-1;

      ////check the inventory item doesn"t exist yet-->look for the index--->this step will be erased with "index" property
      for(int c=0;c<nombre_objets_inventory;c++){
        if(inventory[c].Name==butin[li].Nomobjet){
          tt=c;
        }
      }
    if(tt!=-1){  ////already created
        character[enemyId].AddInventory(inventory[tt]);
      }
      else{  //new creation

//inventaireused is an int that gives me the next free inventory item
      
    inventory[inventaireused].Name=butin[li].Nomobjet;
    inventory[inventaireused].Graphic=butin[li].sprite;
    inventory[inventaireused].CursorGraphic=butin[li].sprite;
    inventory[inventaireused].SetProperty("Couleur", butin[li].couleur); 


/////so this is where I'm going to set : 
inventory[inventaireused].SetProperty("index",li);

    character[enemyId].AddInventory(inventory[inventaireused]);
    
////the function that updates inventaireused
  inventaire_maj();
      }
    }
  }
  } 

Still, this function is another example of checking many occurencies. At the beginning it scans all the items to check wether the specific ennemy is supposed to have it. So anyway I guess I'll encounter the issue. But I'll do what you said and create 500 dummy items to check it works smoothly.

Thanks again :grin:  :grin:  :grin:
#59
Hi guys
I am a bit concerned about something..
I ve been working for the past months on creating a rpg interface in ags. It s not so easy but so far it seems to work.
Thought, I use a lot of what I call a "scanning function" to look for information in my struct of arrays. As so:
(Disregard the syntax errors, I m writing on my phone so it s much more difficult"^^
Code: ags

//Declared as a struct arrays in a script
Item[0].name=hammer;
Item[0].sprite"40;
//...more item stats
Item[1].name=Sword;
Item[1].sprite=41;
//And so on for all the items

//And for instance
Function mouse_over(){
Inventoryitem*selected=inventoryitem.GetatscreenXY(mouse.x,mouse.y);
//Here is the important part:
for int(i=0;i<itemlimit;i++){ 
if (selected.name==item[i].name){
///Do things using the database, like display the stats, etc.
}
}
}

So if it's not clear,I used a previous suggestion from Khris and eeri0 and scan my database for infos. It s a great and easy way to program stuff, and it works perfectly with 10 items.
 Question is, when the system is built and I finally add all the items, Say 200,300,500?(Creating many different items is not the hardest part so there could be many^^) Will this still work as fast or could there be freezes for non gaming computers?
I Guess I m underestimating the performances of a computer, but I would prefer to be sure before I ve spent a year building my system.

Thanks :)


#60
Hi again and sorry I took so long to reply.
I finally could try "on_text_input" and Fontedit. Both are perfect answers to my request.
Thanks a million guys  :smiley:
SMF spam blocked by CleanTalk