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

#21
Could you upload the APK so I can investigate? :-\
#22
Quote from: dayowlron on Mon 21/08/2017 11:35:10inventory[game.inv_activated] is equivalent to player.ActiveInventory.

No, it isn't. The names might be confusingly similar, but they are not intrinsically the same value.

Quote from: The Manualâ,,¢game.inv_activated   Inventory item that the player last clicked on. Useful for unhandled_event.
#23
Quote from: eMTe on Sun 20/08/2017 20:06:21I've replaced the files.

Strange thing is the debug.log HAS NOT been created. The error message I get is very similar thoufg, only with different numbers.

Here's the crash file.

https://bitbucket.org/Maciek_Tr/sosnowy-las/downloads/CrashInfo.3.3.0.1162.dmp

Okay, I actually got this dump to load properly! And, this is totally bizarre, but it says that engine is the NULL pointer.

main.cpp:L117


I have no idea what circumstances might lead AGS_EngineStartup to be invoked with a null pointer. :-X If it's helpful, I can make the debug log start as soon as AGS_EngineStartup is entered, but this seems pretty definitively to indicate where the problem is coming from, which has to do with the engine's invocation of the plugin, and not the actual plugin code itself.

Edit: AGSteam-debug-2.zip will create the log immediately after engine has been assigned in AGS_EngineStartup, and will print the value of engine and lpEngine before continuing.
#24
Quote from: Crimson Wizard on Mon 21/08/2017 00:13:44BTW, that's strange that it failed to init, because I had steam running on background. Maybe I miss something else.

If you just launch the EXE Radiant uploaded above then Steam won't detect it as being a Steam game. You can force this by adding a text file called "steam_appid.txt" with only the text "283880" (no quotes) to the same directory as the EXE and plugin. This alerts the Steam API as to which "app" (game) the EXE is when it's being launched from outside of Steam. Or, as you said, you could just install the game via Steam. 8-)

Thanks for letting me know that it's working up to that point on your end CW.
#25
Please try this version. This will create "agsteam_debug.log" as soon as the "GetClient" function is called, before the AGSteam::Startup function is invoked. The debug log will now print the address of the AGSteamPlugin object and the ISteamUserStats object, which at the very least should verify if one of the pointers is, in fact, a null pointer. This also opens and closes the log file with every write operation, just to fully ensure that the writes are flushed to disk before any crash.
#26
This plugin is being built with Visual Studio 2017 with static linkage to the C++ runtime, so it shouldn't require anything that AGS or Steam don't already depend on. Even if it did, then it should crash much sooner, during the phase where the engine attempts to load the DLL (the plugin). What's happening is that the engine is succeeding in loading the plugin, but then for some reason it's accessing some memory address incorrectly. Which is weird, because the only two pointers being dereferenced are a pointer to a static object and a pointer to an object that the Steamworks API has guaranteed (by the successful return of SteamAPI_Init()) to be valid.

I am already telling the log to flush after every write, but perhaps I'll try closing it after every write operation. The log should be created, no matter what. ??? Curiouser and curiouser.
#27
The long and short of the reply I was about to post is that upon installing Heroine's Quest, running it in and outside of Steam, running it with and without Steam running, and running it directly via the AGS 3.3.0 "acwin.exe", I cannot reproduce a crash of the game using this build of the plugin. I have reuploaded the build to make the process for the user simpler. Have them extract this file on top of the Heroine's Quest files. They must replace "AGSteam.dll" and "steam_api.dll" with the copies enclosed. Then, when they launch the game, a file "agsteam_debug.log" will be created in the game folder. Please have them report back the contents of that file after the game crash (though, honestly, I really suspect that the game won't crash at all).
#28
Well I did try loading the dump file he uploaded, but Visual Studio just reports that it can't find AGSteam.dll. I have tried browsing to the file (both the unified DLL and the disjoint DLL, including renaming the DLL), but the "Open" dialog just doesn't do anything, while in the background under "Binary load information" it keeps appending the message "Can't find or open the PDB file.", despite the two files being in the same location. Perhaps it's something to do with the PDB being out of date with the DLL the game EXE was referencing, but I didn't think DLLs worked that way.

I'll make a debug build (with logging, as you requested) and upload the DLL and the PDB file.

Edit: You can try this build (rename "AGSteam-disjoint.dll" to "AGSteam.dll") (deleted, see new link in following post) and see what results you get. I tested this with AGS 3.3.0 Final "Default Game" and got no problems, with and without Steam running (obviously, without Steam running the plugin simply did not initialize). I downloaded the EXE you posted above (understanding, of course, that it's not the full game and won't be playable), and it raised some questions.

* Heroine's Quest is still using the "disjoint" build, isn't it? You referenced using "AGS2Client" above. The EXE you posted definitely is using the disjoint build, in any case.

* Was Heroine's Quest rebuilt against this version of the plugin? The EXE you uploaded is looking for "AGSteam::FindLeaderboard^1" which was replaced almost two years ago. I had to inject it back in as a reference to RequestLeaderboard with defaulted parameters.

* Is this the same version of the game that's on Steam? I am installing the game now to do some more testing, but I wanted to confirm if it is indeed the same version.

Even before I reinjected FindLeaderboard, the Steamworks API was definitely initializing successfully before the game totally crashed out, as evidenced by the log file. I deleted the log file a few times to be sure.

QuoteSteam not initialized, calling SteamAPI_Init()
SteamAPI_Init() succeeded, creating UserStatsReceivedListener
UserStatsReceivedListener created, requesting current stats
User stats requested, AGSteamPlugin_Initialize() complete
#29
Quote from: Radiant on Sun 20/08/2017 10:31:50adding a try/catch block in SteamAPI_Init could help locate this

Dereferencing a null pointer won't actually throw a C++ exception, so a try/catch block wouldn't help. Just over a month ago, Steamworks v1.41 was released, while the steam_api.dll included in the latest build is from v1.40, but there is no reason to suppose that this would cause such a failure (Valve expressly states that there is no requirement to upgrade).

Quote from: Radiant on Sun 20/08/2017 10:31:50Something else that may be worth checking is whether steam_api.dll is outdated; apparently this is version 3.92.72.58 which has a copyright stamp of 2007. Looking over my Steam library I find numerous versions of this file, but none with a higher version number, and they all have (c) 2007.

Keeping a C/C++ assembly's version information up-to-date is actually far less common than you might expect. Valve just hasn't bothered with it. The steam_api.dll I have bundled is from Steamworks v1.40, only one version behind the latest release.
#30
I never really learned how to use these DMP files, so I'm not particularly sure myself. Hopefully CW has the time and ability to look into it or help explain the steps needed to proceed.
#31
After doing some research into Steamworks.NET, I've determined with reasonable certainty that the AGSteam usage of the Steamworks API does not, in fact, breach the non-disclosure agreement with Valve. Or, in any case, the mere existence of a project like Steamworks.NET has brought the relevant information into public domain through no fault of my own, which is all that I agreed to in the NDA anyway. :=

As such, AGSteam is now open-source. Hopefully this will help track down the problem, because as I said, I can't seem to reproduce it myself.
#32
*bump* for v0.0.3-alpha. Works with AGS 3.4.0 now.
#33
I overlooked a rather obvious (albeit less than ideal) workaround to make the plugin work with AGS 3.4.0, which is simply to create a shallow copy of the "Compiled" folder's contents just before running the jobb tool.

That, and reading that Android engine libraries from the editor's directory are included in v0.0.3-alpha. You need to extract "Android.zip" into "EDITOR_DIRECTORY/Android" (so, "EDITOR_DIRECTORY/Android/armeabi/libags_parallax.so", etc.). The rest should work as previously described. I apologize for not thinking of this approach sooner. (roll)
#34
Unrelated to the issue at hand, but as a matter of logic/style, you should avoid explicitly checking the same thing more than once, especially if a function call is involved. In the same way that CW stored the screen_x and screen_y variables, you should consider storing the walkable area ID or Region*, instead of manually reinspecting the exact same thing. And using else will prevent you having to check the same condition with an inverted operator (that counts as a form of code duplication, and is generally frowned upon). I also recommend using the view names instead of hard-coded view numbers. You can always rename the views if they need to be rearranged for some reason, but if you hard-code their values then you would have to update all of your scripts. Using the names also makes your scripts more legible, which will be helpful six months from now when you've forgotten which view "92" is.

Code: ags
// using walkable areas
function room_RepExec()
{
  int screen_x = player.x - GetViewportX();
  int screen_y = player.y - GetViewportY();
  int walkable_area = GetWalkableAreaAt(screen_x, screen_y);
  if (walkable_area == 2)
  {
    if (player.NormalView == VEGO_NORMAL)
    {
      player.ChangeView(VEGO_LEFTRIGHT);
    }
  }
  else if (player.NormalView == VEGO_LEFTRIGHT)
  {
    player.ChangeView(VEGO_NORMAL);
  }
}


Code: ags
// using regions
function room_RepExec()
{
  Region *rat = Region.GetAtRoomXY(player.x, player.y);
  if (rat == region[1])
  {
    if (player.NormalView == VEGO_NORMAL)
    {
      player.ChangeView(VEGO_LEFTRIGHT);
    }
  }
  else if (player.NormalView == VEGO_LEFTRIGHT)
  {
    player.ChangeView(VEGO_NORMAL);
  }
}


While this probably won't impact your specific use-case here, it will make your code overall easier to read and (marginally) more efficient.
#35
From what CW has said in your other thread, "program pointer is -23" would indicate that the plugin has already initialized.

The AGSteam plugin is still closed-source due to the Steamworks API licensing, but I believe you also have an NDA with Valve for Steam publishing, correct? If necessary, I can discuss further details in private, but I will say here that the latest version of the AGSteam plugin uses the same main.cpp from the AGS2Client source:

Code: ags
void AGS_EngineStartup(IAGSEngine *lpEngine)
{
    engine = lpEngine;

    if (engine->version < 17)
    {
        engine->AbortGame("Engine interface is too old, need newer version of AGS.");
    }

    AGS2Client::GetClient()->Startup();
    AGS2Client::GetClient()->RegisterScriptFunctions(engine);

    engine->RequestEventHook(AGSE_FINALSCREENDRAW);
    engine->RequestEventHook(AGSE_KEYPRESS);
}


AGS2Client::GetClient() returns a pointer, but it is a statically allocated object, much the same as AGS2ClientStub's implementation (which, incidentally, I realize the function name I just linked to was not renamed, though that's completely inconsequential). There is no possibility that the plugin's initialization is dereferencing a null pointer (short of physical memory corruption or the ilk). All other plugin functions should be checking that Steam was initialized before they do anything. Otherwise they should all be no-ops, the same as the stub.

Is it possible to test this with a newer AGS engine and see if similar results occur? Even without Steam running (at all), I can't reproduce this.
#36
Latest builds

There was an issue reported by Dave Gilbert that has been patched in this version, but I got distracted before I updated links and such. This is only the "unified" build (use "AGS2Client.Function()" instead of "AGSteam.Function()"), but I can make sure that the "disjoint" build is uploaded as well in case you're using that. The issue Dave reported may have been the same one regarding a null pointer, which would occur if Steam failed to initialize (namely, if Steam wasn't running).

I will make sure that GetCurrentGameLanguage is added back to the plugin(s).

Edit: As of this writing, I am uploading the latest builds, which have GetCurrentGameLanguage added back in.
#37
Advanced Technical Forum / Re: Queue System
Sat 08/07/2017 18:20:24
Quote from: Morgan LeFlay on Sat 08/07/2017 14:55:42Shouldn't the code be

Code: ags
int rand = Random(max-min) + min;

Yeah, that's right. Sorry, I was getting carried away focusing on... well, anyway. Yes.
#38
Assuming it's a state-saving room (room number < 300), then you should use the room_FirstLoad event instead, because the dimensions/locations of the hotspots are immutable at runtime and the array(s) in your room script will be saved when the room is changed. That makes it only load the data once instead of every time the player enters the room.
#39
Advanced Technical Forum / Re: Queue System
Thu 06/07/2017 12:49:27
Quote from: Snarky on Thu 06/07/2017 10:05:28(The AGS Random() function is one of the stupidest design decisions in the engine.)

In C++, std::rand uses a fixed inclusive min of 0 and a fixed inclusive max of RAND_MAX. std::uniform_int_distribution's constructor takes an inclusive min and inclusive max.

Java (Random.nextInt(int)) and C# (Random.Next(int)) use exclusive max, with a fixed min of 0. C# supplies Random.Next(int min, int max) (inclusive min, exclusive max). Additionally, Java supplies Random.nextInt() which returns any random 32-bit integer (AFAICT, this means the value could be negative and is inclusive from Integer.MIN_VALUE to Integer.MAX_VALUE).

php has rand() and rand(int min, int max). For the former, min is defaulted as 0 and max is defaulted as getrandmax(). Both functions use inclusive min and inclusive max.

There really isn't a general consensus in the programming community of what range "random" should return, even if both min and max are explicit. In AGS, one can achieve an inclusive range [min, max] by using:

Code: ags
int rand = Random(max) + min;


Which is comparable to the same code in other languages. Some languages you may have to specify max + 1 to make max inclusive, but your statement about the design of AGS' Random seems a bit melodramatic.
#40
Quote from: Snarky on Sat 17/06/2017 20:37:24And it doesn't work HOW? What happens when your game gets to that point? If it won't compile, or if it crashes, what does the error message say? "It doesn't work" is not a helpful bug description.



...and the search continues.

We can't help you if you're not describing what is actually happening and what you want/expect to be happening. (wtf) (wrong)
SMF spam blocked by CleanTalk