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

Topics - eri0o

#121
So, I was trying to run my AGS game on Steam OS and for some reason it kept failing on missing libaldmb.so.1 . Now, for the 64-bit version, I use the sdl2 port and use the regular on 32-bit. No matter what I did, the ALLEGRO_MODULES variable wasn't recognised on SteamOS, for the libaldmb.so.1 , so I solved by passing the LD_LIBRARY_PATH - since lib32 / lib64 include the libaldmb.so.1 . I also place the ags binary inside the lib32 / lib64 directories.

Below is what I got that worked consistently across my Linux PCs, through Steam. I pass the full screen modifier because it's needed now in the sdl2 port for some reason.

Code: ags

#!/bin/sh
SCRIPTPATH="$(dirname "$(readlink -f $0)")"

if test "x$@" = "x-h" -o "x$@" = "x--help"
  then
    echo "Usage:" "$(basename "$(readlink -f $0)")" "[<ags options>]"
    echo ""
fi

if test $(uname -m) = x86_64
  then
    export LD_LIBRARY_PATH="$SCRIPTPATH/lib64":$LD_LIBRARY_PATH
    ALLEGRO_MODULES="$SCRIPTPATH/lib64" "$SCRIPTPATH/lib64/ags_sdl2_64" --fullscreen "$@" "$SCRIPTPATH/"
  else
    export LD_LIBRARY_PATH="$SCRIPTPATH/lib32":$LD_LIBRARY_PATH
    ALLEGRO_MODULES="$SCRIPTPATH/lib32" "$SCRIPTPATH/lib64/ags32" "$@" "$SCRIPTPATH/"
fi
#122
I am not very smart and have some trouble understanding documentation. I am trying to release a game on one of those gaming stores.

- should the game installer also install DirectX? This specific store has a redistributable option where I can just select it. It didn't seem to hurt.

- which folder should contain the savegames on Win/Linux/MacOS ? I need to watch them so they can be synced accross computers.
#123
Project:
The AGS Help - a candidate for leading the future in the online help and the Manual!

Details:
I and Morganw have been working a possible candidate for the future of AGS Help.
The still in evaluation help project is hosted in this Github repository.
Discussion on the text and new texts and alterations is done using the repository issues.
The editing of the texts is done through the project wiki. The reading of the texts can be both throught the wiki and the webpage.

Positions Available:
Right now we need a person with AGS experience to do good writing on the visual Editors (Room, Characters, Inventory...) and possibly tutorials. Also someone that can do a reading and find texts that are not correct for current stable version of AGS (3.4.1.13).

You can only work on a page of the manual. If you are interested, you can discuss and write your text directly in the Github Issue page!
Once a task is claimed, I will mark it here with an "x" on the corresponding item.


If you have interest in writing on a different topic, create an issue on the Github issue tracker detailing your interest!

Deadline:
I'm looking to have this written until mid August. I want the project to be considered either mature enough to be moved to the Github AGS organisation or a complete and utter failure so I can test a different solution.
I believe that content generate won't be lost, even though code on the help itself can end being thrown away.

Comments:
Interested parties can reply to this thread or contact me via PM.

UPDATE (29th July):
Hey, the repository moved to the AGS organization on github and the wiki is opened for editing . I've updated the important links on the previous message.
#124
was anyone ever able to recreate leaves animating in low resolution games (320x240 // 320x180) through code in success?

I am looking for an effect similar to the one in Owlboy.

Spoiler


[close]

I looked over the Underwater module, because it's the most similar I could remember, but I don't understand yet how to modify until a flailing effect can be made.

Spoiler

LeavesAnimation.asc
Code: ags

// new module script
#define MAX_FRAMES 10

#define MAX_BLOCKS 128


int block_w;
int block_h;
int block_x[MAX_BLOCKS];
int block_y[MAX_BLOCKS];

bool Leaves_enabled = false;
int original_graphic;

float tt = 0.0;
float t = 0.0;
float a[MAX_FRAMES], b[MAX_FRAMES], c[MAX_FRAMES];

DynamicSprite * dyn_spr;

static void LeavesAnimation::SetBaseGaphic(int leavesGraphic){
  if(dyn_spr!=null){
    dyn_spr.Delete();  
  }
  original_graphic = leavesGraphic;
  dyn_spr = DynamicSprite.CreateFromExistingSprite(original_graphic, true);
}

static int LeavesAnimation::GetGaphic(){
  if(dyn_spr!=null){
    return dyn_spr.Graphic;  
  }
  return 0;
}

static void LeavesAnimation::Enable() {
  float scalar = 8000.0;
  int i = 0;
  
  int delta1 = Random(MAX_FRAMES-1);
  int delta2 = Random(MAX_FRAMES-1);
  int delta3 = Random(MAX_FRAMES-1);
  
  while (i < MAX_FRAMES) {
    a[i] = Maths.Cos(Maths.Pi*IntToFloat((delta1+i)%MAX_FRAMES)/IntToFloat(MAX_FRAMES));  //IntToFloat( Random(2000)*(Random(1)-1) )/scalar;
    b[i] = Maths.Sin(Maths.Pi*IntToFloat((delta2+i)%MAX_FRAMES)/IntToFloat(MAX_FRAMES));  //IntToFloat( Random(2000)*(Random(1)-1) )/scalar;
    c[i] = Maths.Cos(Maths.Pi*IntToFloat((delta3+i)%MAX_FRAMES)/IntToFloat(MAX_FRAMES));  //IntToFloat( Random(2000)*(Random(1)-1) )/scalar;
    i++;
  }
  
  block_w = Game.SpriteWidth[original_graphic]/48;
  block_h = Game.SpriteHeight[original_graphic]/24;
  
  i = 0;
  while (i < MAX_BLOCKS) {
    block_x[i] = Random(Game.SpriteWidth[original_graphic]- 1 - block_w);
    block_y[i] = Random(Game.SpriteHeight[original_graphic] - 1 - block_h);
    i++;
  }
  Leaves_enabled = true;
}

static void LeavesAnimation::Disable() {
  Leaves_enabled = false;
}

float get_gradient_x(int xi, int yi) {
  float x = IntToFloat(xi)/160.0 - 1.0;
  float y = IntToFloat(yi)/160.0 - 1.0;

  float dx = 0.0;
  
  int i = 0;
  while (i < MAX_FRAMES) {
    dx += a[i]*t*Maths.Cos(a[i]*t*x + b[i]*t*y + c[i]);
    i++;
  }
  return dx;
}

float get_gradient_y(int xi, int yi) {
  float x = IntToFloat(xi)/160.0 - 1.0;
  float y = IntToFloat(yi)/160.0 - 1.0;

  float dy = 0.0;

  int i = 0;
  while (i < MAX_FRAMES) {
    dy += b[i]*t*Maths.Cos(a[i]*t*x + b[i]*t*y + c[i]);
    i++;
  }
  return dy;
}

function offset_a_block(DrawingSurface *surf, int x, int y, int w, int h) {
  int xoff = FloatToInt(1.0*get_gradient_x(x + w/2, y + w/2));
  int yoff = FloatToInt(1.0*get_gradient_y(x + h/2, y + h/2));
  
  xoff = Utils.clampInt(xoff, 1, -1);
  yoff = Utils.clampInt(yoff, 1, 0);
  
  //w = Utils.clampInt(w, Game.SpriteWidth[original_graphic]-x, 1);
  //w = Utils.clampInt(w, Game.SpriteHeight[original_graphic]-y, 1);
  
  DynamicSprite *ds = DynamicSprite.CreateFromDrawingSurface(surf, x, y, w, h);
  //surf.DrawingColor = COLOR_TRANSPARENT;
  //surf.DrawRectangle(x, y, x+w, y+w);
  surf.DrawImage(x - xoff, y - yoff, ds.Graphic);
}

function repeatedly_execute_always() {
  if (Leaves_enabled) {
    if(dyn_spr==null){
      return;
    }
    
   if(getCurrentFrame()%4!=0){
      return;  
    }
    
    tt = tt + 0.01;
    float k = Utils.clampFloat((2.0*Maths.Pi*Maths.Sin(tt)), 8.0, 0.0) ; ///8.0;

    t=1.0;

    if(dyn_spr!=null){
      dyn_spr.Delete();  
    }
    dyn_spr = DynamicSprite.CreateFromExistingSprite(original_graphic, true);

    //SetBackgroundFrame(0);
    // repeatedly grab a random chunk from bg 1 and paste it to bg 0, slightly offset
    DrawingSurface *surf = dyn_spr.GetDrawingSurface();  //Room.GetDrawingSurfaceForBackground(0);

    int i = 0;
    while (i < MAX_BLOCKS) {
      if(Random(FloatToInt(k))==0){
        block_x[i] = Random(Game.SpriteWidth[original_graphic]- 1 - block_w);
        block_y[i] = Random(Game.SpriteHeight[original_graphic] - 1 - block_h);
      }
      //int x = Random(Game.SpriteWidth[original_graphic]- 1 - block_w);
      //int y = Random(Game.SpriteHeight[original_graphic] - 1 - block_h);
      offset_a_block(surf, block_x[i], block_y[i], block_w, block_h);
      i++;
    }

    surf.Release();
  }
}


    // draw some more around the player
    // ViewFrame *frame = Game.GetViewFrame(player.View, player.Loop, player.Frame);
    // int graphic = frame.Graphic;
    // int height = FloatToInt(IntToFloat(Game.SpriteHeight[graphic]*player.Scaling)/100.0);
    // int width  = FloatToInt(IntToFloat( Game.SpriteWidth[graphic]*player.Scaling)/100.0);
    // int left = player.x - width/2;
    // int top = player.y - height - player.z;

    // i = 0;
    // while (i < 32) {
    //   i++;
    //   int w = Room.Width/64;
    //   int x = left - w/2 + Random(width - 1);
    //   int y = top - w/2 + Random(height - 1);
    //   if (x < 0) x = 0;
    //   else if (x >= Room.Width - w) x = Room.Width - 1 - w;

    //   if (y < 0) y = 0;
    //   else if (y >= Room.Height - w) y = Room.Height - 1 - w;   

    //   offset_a_block(surf, x, y, w);
    // }


LeavesAnimation.ash
Code: ags

// new module header

struct LeavesAnimation {
  
import static void Enable();
import static void Disable();
import static void SetBaseGaphic(int leavesGraphic);
import static int GetGaphic();

};

[close]

Here is a different gif idea (but I still can't understand how to implement leaf animation on the bg...)
Spoiler


[close]
#125
Very weird question: sometimes I have to just sketch some weird math logic, and I build my game a thousand times just to read the result on a display function. Does an ags script interpreter for only the non graphical functions (maths and String I think) exists? A headless ags of sorts... Maybe AGS Script is based on something of same syntax...
#126
I was procrastinating researching the web and found the below post from Grumpy Gamer (misleading title). If you don't want to read it, go for the video.

https://grumpygamer.com/unit_testing_games

I liked the idea of something randomly playing a game until it crashes and logging the crash. Has someone here ever devised such a tool for an AGS game? (I was'n sure where to place this question...)
#127
Does a Mouse.Click should trigger a on_mouse_click event? If they are in different modules, does order matter? Does Mouse.Click holds button down (for Mouse.isButtonDown) for a single tick?
#128
I need to tint a character portrait - single frame speech view, and no limp sync and no blinking.

I have thought about, but I am not sure how to do it. :(
#129
Hey!

I think since AGS 3.4.1 you can set the line spacing in fonts, over properties, inside AGS. It's awesome!

I just found a little bug, when editing a GUI in the editor (multiline label using [ character), the font LineSpacing is not considered for rendering the GUI in the Editor - but will be considered when the game runs in engine!

Just reporting for now.
#130
Disclaimer: this an article that I sketched long ago, but didn't knew if it was good enough, so I am throwing here to see if ideas can come up to make it better because I want to address this general idea in my blog.

I noticed recently that during the week I am more keen on games that have story depth, but I can get tired if a game is too demanding skill wise. On weekends, I am usually well rested, and like to be challenged.

Once I saw a tweet by @gritfish that said:

Quote"I honestly believe we need to  change the way games do difficulty / game modes to something like:

I'm here for the story
I'm here for challenge
I'm here for a second & harder playthrough
I'm here to take photos
I want to play with the settings and I'm okay if that breaks things
"

Well, I like this idea. But I am also slightly lazy, I am not coding different game modes.

I've read Designing Virtual Worlds, from Richard Bartle, and he talks about the 4 types of players he discovered while analyzing MUD: Achievers, who like to achieve defined goals; Socializers, who gets greatest rewards interacting with other people; Explorers, who likes to learn more about the virtual world; Killers, who like to dominate others. He goes on to explain how to create a virtual world that attracts each subset of players.

Players of Magic The Gathering may be familiar with this idea, it's R&D and Mark Rosewater divide players in three categories: Timmy, a social person who wants to have fun winning big (the RTS equivalent would be having a big base before unleashing a final gigantic attack); Johnny, who wants to express himself through the game; and Spike, who plays for the winning and competition. Recently they also started considering hybrids of these players.

On with adventure games. They are mostly known by stories, puzzles, the exploring and the pace on the control of the player. Psychographics can be defined as a quantitative methodology used to describe consumers on psychological attributes. Psychographics has been applied to the study of personality, values, opinions, attitudes, interests, and lifestyles.

I would like to propose here psychographics for Point and Click Adventure Games:

- Stella, who plays for the Story;
- Paula, who plays for the Puzzles;
- Ezra, who plays to Explore;

So each time I create a room in a game, I try to look if I am leaving each of these players, something to play with, and also, I usually choose one of them to focus more on each room.
#131
Hello,

I need to get the current graphic from the player, I need to do this every instant, I am using this information to draw things on a surface, so at instant t=7 I need the player frame for instant t=7, and not t=6.

I decided to use the following:

Code: ags

int getPlayerGraphic(){
  ViewFrame * ViewFrame_Player;
  ViewFrame_Player = Game.GetViewFrame(player.View,  player.Loop, player.Frame);
  return  ViewFrame_Player.Graphic;
}


but apparently, this gets in the current instant, the graphic that was on screen on the previous instant, so using this information gets a slightly delay.

So I evolved to do the following thing:

Code: ags

int i_view;
int i_loop;
ViewFrame * ViewFrame_Player;

function repeatedly_execute_always(){
  i_view = player.View;
  i_loop = player.Loop;
}

function late_repeatedly_execute_always(){
  if(IsGamePaused() == 1  || !System.HasInputFocus){
    return;  
  }
  
  ViewFrame_Player = Game.GetViewFrame(i_view,  i_loop, player.Frame);
}

static int PlayerViewframe::getGraphic(){
  return  ViewFrame_Player.Graphic;
}


which sometimes works, but in some rare occasions, crashes my software, because player.Frame sometimes is updated and i_view and i_loop isn't, and my loop for down and up have different frame count than left and right. And sometimes, it doesn't update correctly.

So is there a right way of getting the current graphic the player has ?
#132
Please check the Editor manual pages below if you are building with the Editor!

https://adventuregamestudio.github.io/ags-manual/BuildAndroid.html
https://adventuregamestudio.github.io/ags-manual/DistGame.html#compiled-folder-structure
https://adventuregamestudio.github.io/ags-manual/GeneralSettings.html#android
https://adventuregamestudio.github.io/ags-manual/EditorPreferences.html#android

Below follows information if you instead are using Android Studio yourself and diving in AGS source code.



>> The documentation for releasing for Android is here: [tt]README.md[/tt] <<

Please in case of trouble ask here in this thread! It's possible I screwed up somewhere too, so report any problems!

Note: due to Google Play App size limits, it's important your game not be bigger than 1GB. You can put some files in the app bundle and the rest on the install time asset pack if you need it to be just a bit (100MB) bigger.

---

The information below is outdated, it was relevant for old Android port.
Spoiler

I will try to explain what I did here, questions will arise, hopefully everything can be answered here and this will allow me to generate a guide.

So first two things are important:
- Android port of the engine currently doesn't report correctly mouse.isButtonDown, so your game CAN'T BE USING THIS, use if(System.OperatingSystem == eOSAndroid) in your code to work for this.
- I am using the latest prebuilt APK as libs, those were for the previous stable version, so your game must be built with that AGS.

1. You need to install the latest Android Studio, just download and install. https://developer.android.com/studio/index.html .

2. You will also need JDK, NDK and Android SDK.

3. After installing Android Studio, download the repository I made here: https://github.com/ericoporto/mythsuntold_dungeonhands . This is my modded version of Monkey's Android Studio Project.

4. Open the folder in Android Studio.

5. Building should generate my game .apk!

6. Ok, let's make YOUR game .apk. In the folder Android Studio placed the Sdk, there is a magical tool called jobb. I use Ubuntu, and the tool is in the folder ~/Android/Sdk/tools/bin/ in my computer. If you use Windows, then it's probably in %appdata%\Local\Android\Sdk . (if someone can confirm this information, it would be awesome!). This is just so you can understand what will happen next.

7. In your game Compiled folder, there is a YOURGAMENAME.ags file. Open a cmd.exe (windows) or bash terminal (Linux/OSX). Change Directory to the folder YOURGAMENAME.ags is.

In Windows (untested!)
Code: cmd
cd YOURGAMENAME\Compiled\
mkdir obb
move YOURGAMENAME.ags obb\
%appdata%\Local\Android\Sdk\tools\bin\jobb -d \obb\ -o main.3.com.YOURSTUDIONAME.YOURGAMENAME.obb -pn com.YOURSTUDIONAME.YOURGAMENAME -pv 3
 
In Linux/OSX
Code: cmd
cd YOURGAMENAME/Compiled/
mkdir obb
mv YOURGAMENAME.ags obb/
~/Android/Sdk/tools/bin/jobb -d ./obb/ -o main.3.com.YOURSTUDIONAME.YOURGAMENAME.obb -pn com.YOURSTUDIONAME.YOURGAMENAME -pv 3

In the code above, 3 is simply the OBB version number. Every time you change the content of the OBB linked to your APK and release, you have to increase that number - and update in your Android Studio Project accordingly. Also make sure that YOURGAMENAME and YOURSTUDIONAME are correctly updated in your android studio project.

8. In the README there is a line called Setting up the project for your game. I will copy below:

-Update package name:

Open the project in Android Studio, then in the project tree navigate to app/java/com.mythsuntold.osd.scourge.
Right-click on this folder and select "Refactor -> Move...". When prompted, select "Move package 'com.mythsuntold.dungeonhands' to another package" (the default). You may receive a warning that multiple directories will be moved, select Yes. Type the parent name of your package, not the final package name (e.g., com.bigbluecup not com.bigbluecup.game), select "Refactor" and then click "Do Refactor".
Right-click on the new project folder in the project tree (e.g., com.bigbluecup.scourge) and select "Refactor -> Rename". Type the package name for your game (e.g., game), then select "Refactor" and click "Do Refactor".

Finally, delete the com.mythsuntold.dungeonhands folder.

- Update project.properties. This file contains gradle settings related to your project. The application ID, version code, and version name need to be set to match your project settings (application ID is your package name).

- Update project.xml. This file contains resources for your project. The values there are described in that file.

- Update local.static.properties. This file contains local data that should NOT be added to version control (.gitignore will ignore your changes to this file). You need to add your keystore path, alias, and passwords, and optionally the path to your copy of the AGS source (if you are rebuilding the engine native libraries). See the Java docs on keytool or use the Android Studio signing wizard to generate a keystore.

- Update private.xml. This file contains definitions for your RSA public key and an integer-array with bytes for your salt which is used by the ExpansionDownloaderService. These values are necessary if distributing your app via the Google Play Store. The RSA public key is provided in the Google Play Developer Console, and the salt bytes may be any number of values in the range [-128, 127]. You may need to upload an APK without the RSA public key first before the key is provided. That APK should not be public unless the OBB file is embedded.

- Update graphics resources (app/src/main/res). You can use the Android Asset Studio to easily generate graphics for your app, or use your preferred method. Everything in the drawable and various mipmap-* folders should be replaced with your resources.

I made this post with the intent to help Mehrdad, so please try this!
[close]
#133
Just linking a website that has been very useful to me:

http://www.pentacom.jp/pentacom/bitfontmaker2/gallery/?page=1&order=popular
#134
There are some links that goes to Teamcity bigbluecup, it looks like it is/was a pipeline part to build binaries. Is this still online? Are the scripts for build there public in any place?
#135
Hello,

I am making the opening scene of my game and I have a question. Playtesting showed that players prefer dialogs to be click to advance only instead of click + timer. In the opening scene though, I feel it would be better if the dialog used click to advance plus timer, because each looping state feel better under a time constraint.

Would keep my game click to advance and the opening click to advance + timer be a good or a bad idea?
#136
I noticed the music position in ms is not updated every frame. Is this intentional?

I came up with the following code to fix this, where actualACMusMs has the true music position:

Code: ags

AudioChannel *acMusic;

//fix to report correct music position, game in 60fps
int frame;
int acMusPreviousMs;
bool startedRepeat;
int frameWhenRepeatingStarted;
int actualACMusMs;

void playMusic(AudioClip * musicClip){ 
  acMusic = musicClip.Play(eAudioPriorityHigh, eRepeat);
}


void repeatedly_execute_always(){
  if(IsGamePaused()==1 || acMusic==null){
    return;  
  }

  frame++;
  
  if(acMusic.PositionMs==acMusPreviousMs){
    if(!startedRepeat){
      frameWhenRepeatingStarted=frame-1;
    }
    startedRepeat=true;
    actualACMusMs = acMusPreviousMs+(frame-frameWhenRepeatingStarted)*16;
  } else {
    startedRepeat=false;
    actualACMusMs= acMusic.PositionMs;
  }
  
  acMusPreviousMs = acMusic.PositionMs;
}


I did this because I am experimenting with some music in my game that is active, like, I switch music depending on changes on the environment, and needed to correctly position the music when switching.

Also, imagine a graph:

(music 1)--->>(music 2)<< loop music 2 forever

How would you detect music 1 has ended and you need to proceed to music 2? Also if I have crossfade activated, how should I force crossfade to not happen then?
#137
Hey! When I alt+tab an AGS game, the audio likely rolls a dice, and on a odd number, it glitches, producing looping sound that sounds like the previous 200ms of sound. Is there a way to prevent this? If I could detect from in game the loss of focus, I could try to lower the volume.
#138
Hey, I have a code as below, my character cChara is correctly shown in screen. But SOMETIMES, I get an error on the line that has Game.GetViewFrame, stating Error: GetGameParameter: invalid frame specified.

Code: ags

ViewFrame * tvf;

...
function late_repeatedly_execute_always(){
  ...
  tvf = Game.GetViewFrame(cChara.View, cChara.Loop, cChara.Frame);
  ...
}


The only thing I gathered is it happens when the character is walking to some direction and I click to force him walk down, and my walking down (and up) animation has one less frame then the walking right and left.
#139
Ok, so today I lost some hours of my life coding NormalMap with AGS Script.

In case you want it, Download the Demo here!.

I don't think it looks good, I decided to ditch this idea, but maybe someone wants to try and test this.

I based my code on the code here.

If someone does make it better, faster, please share your enhancemets here!

#140
Completed Game Announcements / Dungeon Hands
Tue 05/12/2017 01:36:19
Dungeon Hands

Dungeon Hands is a two player card game you can play on a computer, made for LudumDare40. Click and drag to move cards. Click gif above to play game.


Ludum Dare 40 entry
  • Music and Graphics by Ricardo Juchem
  • Game Design by Kamila Galvani
  • Code and Stuff by Érico Porto


Here are the rules

You win when you have no cards in hand.

When the game starts players can choose Monster Overlord or Heroes. The player with Monster Overlord deck starts.

A round is composed of each player turns.

On the start of the turn, the player can play any special card if desired. Then the player must play either a Hero card (when playing with Heroes) or a Monster card (if you are the Monster Overlord). Then the game goes to next turn.

The player playing next can play any special card if desired. Then the player must play either a Hero card (when playing with Heroes) or a Monster card (if you are the Monster Overlord), but the card played MUST be either a higher Rank or the same Class, this is called a valid card. If a player does not have a valid card in his hand, that player draws cards until a valid card is drawn and played. Then the turn ends.

With Monster Overlord cards and Heroes cards on the table, the dungeon encounter is resolved, and all cards on table leave play - the Hero cards go back to the village and the Monsters cards perish. The player who had the highest Rank card get to start the next round. If all cards had the same Rank, the last player to play starts the next round.

The Rank is the number on the corner, Class is represented by the symbol and color of the card. Special cards have no Rank or Class.

The player who draws the last deck card loses.
SMF spam blocked by CleanTalk