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 - Hernald

#41
It seems that the majority are in favour of releasing a bad first game as a learning experience, but only after having it play tested.
Incidentally I'm looking for a couple of people to play test my first game; see the recruitment thread: http://www.adventuregamestudio.co.uk/forums/index.php?topic=47102.0
#42
Supposing you were close to completing your first AGS game and looked up for a few minutes to compare it with other people's offerings
- and realized you really should have learned the basics of graphic design first, or at least come up with a coherent story...
Would you go ahead and release it anyway? Would you announce it on the Games Completed thread? Or would you bury it and start again from scratch?
I am interested in both sides of this, and any positions in between - supported by reasoning, obviously.
(And remember, we are considering if this was YOUR game; I'm admitting to nothing!)
#43
Project: Baldy's Adventure

Details: The hero is a handyman who has to look for his missing dog, get to his toolbox and resolve a few other problems. He visits his neighbours, the forest, the wasteland and the Ziggurat - home to mysterious deities in his quest to defeat Rupert Grimes the landlord.
http://www.adventuregamestudio.co.uk/forums/index.php?topic=47101.0

There are over thirty rooms and a dozen characters.

Positions available: I would like two or three people to go through the game checking for bugs and generally making sure the game is playable; it's hard to see some things when you've been up close to them for over a year.
There is music in the game, but it is from a royalty free site; If anyone fancies helping me make my game a little more unique I would be happy to listen to your creations and maybe use them.

Deadline: I would like to have this ready to go by the end of the year, but my absolute final deadline is the end of March next year, just in case there is anything that needs serious fixing.

Comments: PM me or reply to this thread. It would help if you had the use of Dropbox for the zip file of the game as I am having trouble uploading it to MediaFire at the moment. The file is about 90MB at I can send you a Dropbox or RapidShare link.
#44
Baldy wakes up to find his dog William is missing, then he manages to barricade himself out of his house!
In sorting out these and other problems he visits his neighbours, the forest, the wasteland and the Ziggurat - home to strange gods and faces the unsavory Rupert Grimes!















Development Progress:

Story: 100%
Scripting: 99% ?
Graphics: 99% ?
Sound/Music: 99% ?

This is my first attempt at a point and click adventure game.
It's basically done, but I need a couple of people to have a go at it and see if I missed anything.
http://www.adventuregamestudio.co.uk/forums/index.php?topic=47102.0

#45
Good idea! I'll try that and let you know how it goes.

... I just played through my game without it crashing!
This was how I changed the code:
Code: AGS

      // MAKE RECTANGLE INVISIBLE 
      if (this.GetProperty("background_rect")==1) {
        cRectangle1.Transparency=100;
        tempvf = Game.GetViewFrame(cRectangle1.View, cRectangle1.Loop, cRectangle1.Frame);
        tempvf.Graphic=1117;
        if (vOldSprite1!=null) vOldSprite1.Delete();
      }
      else if(this.GetProperty("background_rect")==2) {
        cRectangle2.Transparency=100;
        tempvf = Game.GetViewFrame(cRectangle2.View, cRectangle2.Loop, cRectangle2.Frame);
        tempvf.Graphic=1118;
        if(vOldSprite2!=null) vOldSprite2.Delete();
      }

Thanks for the advice Crimson Wizard.
I will play the game through again two or three times in the next week and if all's well I'll mark this as solved.
#46
Could the problem be caused by making a Character's View out of dynamic sprites?
#47
Thanks for that pointer Khris, I'll get onto it.

... That made my code more efficient, unfortunately it didn't stop my game from crashing. This time it wasn't particularly close to a Changeview.
I will keep trying things out, let me know if there's anything else I can tell you.
#48
On second thoughts; I think I will wait to see what people say about the code I have posted before adding any more Deletes.
#49
Thanks for getting back to me Crimson. I will post some selected highlights of the code here over the next few days.

...Okay. Having taken another look at my code I realize there should probably be a lot more Deletes in it. I will get onto that;
but as the problem is probably the Deletes I have put in rather than the Deletes I have left out I will focus on them.

There are a couple of instances in my Speak code where vOldSprite is declared globally:
Code: AGS

// Speak: Say with a background panel.

void Speak(this Character*, String message) {
  int wid;
  int hei;
  int lines;
  int maxwid = 428;
  int lesswid = 290;//257

  int newwid;
  
  int leftside = 160;
  int rightside = 480;
 
  int savewid;
  
  int char_width;
  int char_height;
  ViewFrame *char_frame;
  DynamicSprite *char_sprite;
  
  bool HotsVis;
  
  // Get Character dimensions.

  char_frame = Game.GetViewFrame(this.View, this.Loop, this.Frame);
  char_sprite= DynamicSprite.CreateFromExistingSprite(char_frame.Graphic);
  char_width=char_sprite.Width;
  char_height=char_sprite.Height;
   
  if (char_sprite!=null) char_sprite.Delete();

// Get speach position & dimensions
  int sayx;
  int sayy;
  sayx=this.x; 
  sayy=this.y-(char_height*this.Scaling/100)-this.z;



  wid=GetTextWidth(message, eFontSpeechOutline);
  
  
  savewid=wid;
  newwid = maxwid;
  if (this.x<leftside+GetViewportX()||this.x>rightside+GetViewportX()) newwid=lesswid;
  if (wid>newwid)wid = newwid;
  
  if (this.x-(wid/2)<GetViewportX()) sayx=GetViewportX()+(wid/2);
  if (this.x+(wid/2)>640+GetViewportX()) sayx=640+GetViewportX()-(wid/2);

  hei=GetTextHeight(message, eFontSpeechOutline, wid);
  hei+=5;
  if (sayy-hei<8) sayy=hei+8;

// Set size of word balloon
  ViewFrame* rectframe;
  DynamicSprite* rectsprite;

  rectframe=Game.GetViewFrame(cRectangle.View,cRectangle.Loop, 0);
  rectsprite=DynamicSprite.CreateFromExistingSprite(1116);
  rectsprite.Resize(wid, hei);
  rectframe.Graphic=rectsprite.Graphic;
  if (vOldSprite!=null) vOldSprite.Delete(); 
  vOldSprite=rectsprite;

  if (gHotSpot.Visible) {
    HotsVis=true;
    gHotSpot.Visible=false;
  }
  else {
  HotsVis=false;
  }
  
  
  
// Position message
  cRectangle.Transparency=100;
  cRectangle.ChangeRoom(this.Room, sayx, sayy);
  cRectangle.Baseline=480;

// Show message
  cRectangle.Transparency=30;
  this.Say(message);
  cRectangle.Transparency=100;
  
  if (HotsVis) gHotSpot.Visible=true;

}


The second place dynamic sprites are deleted is in my amended version of BackgroundSpeech where vOldSprite1 and vOldSprite2 are global:
Code: AGS

// Copyright (C) 2007-2009 Tom Vandepoele
//-------------------------------------------------------------------

AudioChannel* Channel[];
bool BgTalkActive[];
Overlay* Overlays[];
int Views[];
int Timers[];

function game_start()
{
   int ch_idx;
   Channel = new AudioChannel[Game.CharacterCount];
   BgTalkActive = new bool[Game.CharacterCount];
   Overlays = new Overlay[Game.CharacterCount];
   Views = new int[Game.CharacterCount];
   Timers = new int[Game.CharacterCount];
   
   ch_idx = 0;
   while (ch_idx < Game.CharacterCount)
   {
      BgTalkActive[ch_idx] = false;
      ch_idx++;
   }
}

// monkey_05_06 ... CreateTextual with Alignment!

import Overlay* CreateTextualOverlayAligned(int x, int y, int width, FontType font, int color, String text, Alignment=eAlignCentre);

Overlay *textOverlay;

Overlay* CreateTextualOverlayAligned(int x, int y, int width, FontType font, int color, String text, Alignment align) {
  int height = GetTextHeight(text, font, width);
  DynamicSprite *sprite = DynamicSprite.Create(width, height);
  DrawingSurface *surface = sprite.GetDrawingSurface();
  surface.DrawingColor = color;
  surface.DrawStringWrapped(0, 0, width, font, align, text);
  surface.Release();
  Overlay *newOverlay = Overlay.CreateGraphical(x, y, sprite.Graphic, true);
  if (sprite!=null) sprite.Delete();
  return newOverlay;
}

function ShowTextCentered(String text) {
  int width = GetTextWidth(text, Game.NormalFont);
  int height = GetTextHeight(text, Game.NormalFont, width);
  int x = (System.ViewportWidth / 2) - (width / 2);
  int y = (System.ViewportHeight / 2) - (height / 2);
  textOverlay = CreateTextualOverlayAligned(x, y, width, Game.NormalFont, 17238, text);
}

/**
* Have the character say (animation + sound) something in the background.
* Note! The talking character will not have lip sync to either the audio or the text.
**/

function StopSayInBackground(this Character*)
{
   if ((BgTalkActive[this.ID]) &&
       (null != Overlays[this.ID]))
   {
      if (null != Channel[this.ID])
      {
         Channel[this.ID].Stop();
      }
      
      if (Overlays[this.ID].Valid)
      {
         Overlays[this.ID].Remove();
      }
      
      if (0 != Views[this.ID])
      {
         this.UnlockView();
      }
      
      BgTalkActive[this.ID] = false;
      
      // MAKE RECTANGLE INVISIBLE 
      if (this.GetProperty("background_rect")==1) {
        cRectangle1.Transparency=100;
        if (vOldSprite1!=null) vOldSprite1.Delete();
      }
      else if(this.GetProperty("background_rect")==2) {
        cRectangle2.Transparency=100;
        if(vOldSprite2!=null) vOldSprite2.Delete();
      }
   }
 
 
}

function SayInBackground(this Character*,  String message, AudioClip *clip, int view, AudioPriority priority)
{
   this.StopSayInBackground();
   
   int text_width;

   text_width = GetTextWidth(message, Game.SpeechFont) * 2; 
  
   if (text_width > (System.ViewportWidth /2))
   {
      text_width = System.ViewportWidth /2;
   }


   int text_height = GetTextHeight(message, Game.SpeechFont, text_width);

   
   // Get Character dimensions
   
   int char_width;
   int char_height;
   ViewFrame *char_frame;
   DynamicSprite *char_sprite;
   
   char_frame = Game.GetViewFrame(this.View, this.Loop, this.Frame);
   char_sprite= DynamicSprite.CreateFromExistingSprite(char_frame.Graphic);
   char_width=char_sprite.Width;
   char_height=char_sprite.Height;
   
   if (char_sprite!=null) char_sprite.Delete();
      
   
   /* The x position of the overlay is calculated by the character's sprite width and the text width   */
   /* The y position of the overlay is calculated by the character's sprite height and the text height */

   int text_x = this.x  + (char_width / 2) - text_width;
 
   if (text_x + text_width > 631 ) {
     text_x = 631 - text_width;
   }
   else if (text_x < 8 ) {
     text_x = 8;
   }

   int text_y = this.y - this.z - (char_height + text_height);
   
   if (text_y < 8){
     text_y = 8;
   }
   else if (text_y + text_height > 471) {
      text_y = 471 - text_height;
   }
  
// GET SIZE AND POSITION OF RECTANGLE, PLACE IN ROOM AND MAKE VISIBLE
   Character* cThisRect;
   int RectNum;
   int ThisSprite;
   ViewFrame* rectframe;
   DynamicSprite* rectsprite;
   if (this.GetProperty("background_rect")==1) {
     cThisRect=cRectangle1;
     ThisSprite=1117;
     RectNum=1;
   }
   else if(this.GetProperty("background_rect")==2) {
     cThisRect=cRectangle2;
     ThisSprite=1118;
     RectNum=2;
   }
   else {
     Display("Background Rectangle for Character SayInBackground is not set or invalid.");
   }


   rectframe=Game.GetViewFrame(cThisRect.View,cThisRect.Loop, 0);

   
   rectsprite=DynamicSprite.CreateFromExistingSprite(ThisSprite);
   rectsprite.Resize(text_width,text_height);
   rectframe.Graphic=rectsprite.Graphic;
   if (RectNum==1) {
     vOldSprite1=rectsprite;
   }
   else {
     vOldSprite2=rectsprite;
   }
   Wait(1);


// Position message
   cThisRect.Transparency=100;
   cThisRect.ChangeRoom(this.Room,text_x+(text_width/2),text_y+text_height);
   cThisRect.Baseline=480;

// Show message
   cThisRect.Transparency=30;

   //Overlays[this.ID] = Overlay.CreateTextual(text_x, text_y, text_width, Game.SpeechFont, this.SpeechColor, message);
   Overlays[this.ID] = CreateTextualOverlayAligned(text_x, text_y, text_width, Game.SpeechFont, this.SpeechColor, message, eAlignCentre);

   Timers[this.ID] = GetGameSpeed() * (message.Length / 10);

   Channel[this.ID] = null;
   if (null != clip)
   {
      Channel[this.ID] = clip.Play(priority);
   }
   
   if (null != Overlays[this.ID])
   {
      Views[this.ID] = view;
      if (0 != view)
      {
         this.LockView(view);
      }
      
      this.Animate(this.Loop, this.SpeechAnimationDelay, eRepeat, eNoBlock);
      BgTalkActive[this.ID] = true;
   }
}

function BackgroundTalkActive(this Character*)
{
   return BgTalkActive[this.ID];
}

function repeatedly_execute()
{
   int ch_idx = 0;
   
   while (ch_idx < Game.CharacterCount)
   {
      if ((BgTalkActive[ch_idx]) &&
          (null != Overlays[ch_idx]))
      {
         if (Timers[ch_idx] > 0)
         {
            Timers[ch_idx]--;
         }
         
         if (null != Channel[ch_idx])
         {
            if (Channel[ch_idx].PlayingClip == null)
            {
               Channel[ch_idx] = null;
            }
         }
         
         if ((0 == Timers[ch_idx]) &&
             (null == Channel[ch_idx]))
         {
            Overlays[ch_idx].Remove();
            
         // MAKE RECTANGLE INVISIBLE 
            if (character[ch_idx].GetProperty("background_rect")==1) {
              cRectangle1.Transparency=100;
              if (vOldSprite1!=null) vOldSprite1.Delete();
            }
            else if(character[ch_idx].GetProperty("background_rect")==2) {
              cRectangle2.Transparency=100;
              if (vOldSprite2!=null) vOldSprite2.Delete();
            }
            
            Overlays[ch_idx] = null;
            if (0 != Views[ch_idx])
            {
               character[ch_idx].UnlockView();
            }
            BgTalkActive[ch_idx] = false;
         }
      }
      
      ch_idx++;
   }
}


I expect I have made a beginners error here, but the fact that CJ was taking an interest in this error message a year or so ago prompted me to put it in Advanced. I will get back to putting Deletes where they should be and hope that someone can point out what I've done wrong here.
Incidentally, I am using the Credits and Flashlight modules as well but I haven't tampered with them (much) so I expect the problem doesn't lie there.

Thanks in advance for your help.
#50
I get the following message as my game crashes about once every playthrough
Quote
An internal error has occured. Please note down the following information.
If the problem persists, please post the details on the AGS technical forum.
(ACI Version 3.21.1115)

Error: SpriteCache::removeOldest: Attempted to remove sprite 1200 that does not exist

This problem has been raised before on the forums but I haven't seen a solution.
Any suggestions?

P.S. I am using dynamic sprites. What I've noticed is that the crashes tend to happen shortly after a Changeview, but not always the same one, and when I resume the game from the last save it doesn't crash in the same place.
#51
I like this! It's nice bright cartoony stuff. If you could find a way for the character to cast a shadow it would be even better.
What did you use to model the environment and character? Was it Blender?
#52
Hints & Tips / Re: Lost Prince of Lorden
Sat 15/09/2012 10:58:02
Quote from: partydoc on Sat 15/09/2012 10:05:19
Hi folks,

this really never happened to me before, but I'm already stuck at the very beginning...

Spoiler
I spoke to the thief, I found out about the way going south barried with bushes, I would need something sharp... But I only have my medaillon. The forest is too dark... I already did pixel hunting, but there seems to be no more hotspot to interact with. The spider web looks interesting, but also - nothing I can do with it.
[close]

What am I missing?
Spoiler

More pixel hunting: Near the moat on the grass; it doesn't stand out at all.
[close]
Question: A bit further on; has anyone found the
Spoiler
shovel
[close]
yet?
#53
Eight pixels was nowhere near enough for one line let alone multiple lines.
I've  copied up the GetTextHeight function from dialog_options_render to dialog_options_get_dimensions and now it works perfecly:
Code: AGS


function dialog_options_get_dimensions (DialogOptionsRenderingInfo *info){
  int ocount=0, oindex=1;
  
  
  info.X = 40;
  info.Width = 560;
  vDialogHeight=0;
  
  while (oindex <= info.DialogToRender.OptionCount) {
    if (info.DialogToRender.GetOptionState(oindex) == eOptionOn) {
      vDialogHeight+=GetTextHeight(info.DialogToRender.GetOptionText(oindex), eFontSpeech, info.Width - 10);
      ocount++;
    }
    oindex++;
  }

  vOptionCount=ocount;
    
  info.Y = 470 - vDialogHeight;
  
  info.Height = vDialogHeight;
  
  vDialogNo=info.DialogToRender.ID;

}

It was a basic programming issue as I'd hoped; I guess I'd been at it for a while and needed to give my brain a rest, and a fresh perspective.




#54
cat: You were right! The problem was caused by me not measuring the height of the rows of text in dialog_options_render.
I've simplified that code a bit and given the font more space and now it is working fine!
Thank you both for your input.
#55
Khris: Yes, I had tried it that way earlier; anything other than a simple uncalculated integer seems to come out wrong;
cat: The dialog_options_render is taken straight from the manual with just the background colour and font changed. Okay I'll post it in case I've messed something up:
Code: AGS


function dialog_options_render(DialogOptionsRenderingInfo *info)
{
  // Clear the area pale green
  info.Surface.Clear(36269);
  int i = 1,  ypos = 0;
  // Render all the options that are enabled
  while (i <= info.DialogToRender.OptionCount)
  {
    if (info.DialogToRender.GetOptionState(i) == eOptionOn)
    {
      if (info.ActiveOptionID == i) info.Surface.DrawingColor = 13;
      else info.Surface.DrawingColor = 4;
      info.Surface.DrawStringWrapped(5, ypos, info.Width - 10, 
                         eFontNormal, eAlignLeft, info.DialogToRender.GetOptionText(i));
      ypos += GetTextHeight(info.DialogToRender.GetOptionText(i), eFontNormal, info.Width - 10);
    }
    i++;
  }
}


Thank you both for coming back to me, but I'm afraid I'm still in the dark...
#56
I hope this is a simple scripting problem.
I am creating a custom dialog and no matter what I try the Height of the options box is rendered at what seems to be an arbitary value.
The code is picking up the right dialog, and calculating the number of options and the Height correctly, but this Height and corresponding Y value are not being used.
Here is the code:

Code: AGS


function dialog_options_get_dimensions(DialogOptionsRenderingInfo *info){
  int ocount;
  int oindex;
  ocount=0;
  oindex=1;
 
  info.Y = 470;
  info.Height = 0; 
 
 
  while (oindex <= info.DialogToRender.OptionCount) {
    if (info.DialogToRender.GetOptionState(oindex) == eOptionOn) {
      info.Y -=8;
      info.Height +=8;
      ocount++;
    }
    oindex++;
  }
  vDialogNo=info.DialogToRender.ID;
  vOptionCount=ocount;
  vDialogHeight=info.Height;

  info.X = 40;

  info.Width = 560;

}



Any help or advice appreciated.
#57
Look up 'File Functions and Properties' in the manual; this will tell you how to read and write files at runtime.

Doing this will be unlikely to help you avoid the game crashing when a player tries to resume a game after you have made changes to the code, especially if you have added new variables. Can you be absolutely sure that you won't want to change what information you include in these files?

The example you give of how this file would be used is not going to work; Using 'if' statements in this way would mean you would have to code for every possible permutation of variables that you might be reading. Better to read in a number of integers and have them update globals. Better still, use the standard game saves and test your game properly before visiting it on players.

#58
You've set the timer just before you check if it's expired; doing it that way, it never will.
Take the first SetTimer out of the RepExec loop and put it in the AfterFadeIn or somewhere like that.

Also close the if statement with a final curly bracket. And the RepExec function as well.
#59
In the manual : Predefined global script functions - unhandled_event
#60
Sorry Khris. I'll get back to my game.
SMF spam blocked by CleanTalk