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

#1
Huh, you use
Spoiler
TROUT
[close]
as a common guess? I usually try to avoid guessing words with repeat letters, in order to test as many possibilities as possible. (In this case I guessed
Spoiler
GROUT
[close]
before I got it.)
#2
Quote from: Crimson Wizard on Fri 02/05/2025 12:26:26Why do you have to replace this manually instead of using "import over this font" button?

The import dialog didn't use to support WFN files either, so you had to use this workaround. I think it's been fixed for a while now, but old habits...
#3
To find suitable low-resolution fonts you can search for "pixel fonts."

Various Sierra and LucasArts fonts are also available here: https://helmet.kafuka.org/sci/fonts/ (in .fon format, which AGS doesn't read—unless it's actually the same as the SCI .001 (etc.) format—but it's easy to find converters to more common formats).
#4
I don't seem to have a copy of the SCI files available. I don't think they're much used in recent years. But let's ping @AGA about the broken link; maybe he has them somewhere.
#5
The Rumpus Room / Re: What grinds my gears!
Fri 25/04/2025 15:32:36
Quote from: VampireWombat on Fri 25/04/2025 14:47:34But it's better to identify the possibility of being neurodivergent and doing what's possible to help than to avoid thinking you're neurodivergent out of fear of being bullied by people who say you can't self diagnose. I'm not saying you or Snarky are bullying, but there are subreddits that do basically bully people for what they think of as faking autism.

Thanks. I wasn't hoping to get into an argument with you or anyone over this, or bully anyone. Your experiences are of course valid, and I'm not saying that a (tentative!) self-diagnosis cannot be useful to an individual. It's the (online) discourse around it that rubs me the wrong way – in some cases.

The tendency for people to be foolish and obnoxious is a human constant, it just takes different forms in different eras. It seems pretty clear to me that neurodivergent labels have become trendy in a way that attracts frivolous claims – the way gluten intolerance was trendy a couple of decades ago – or even malicious misuse (see: Elon Musk, or Neil Gaiman using a supposed autism diagnosis as a defense against sexual abuse allegations).
#6
The Rumpus Room / Re: What grinds my gears!
Thu 24/04/2025 11:24:12
Quote from: Blondbraid on Thu 24/04/2025 10:32:09It also ties into a larger problem of young people online who self-diagnose based on the idea that things like feeling lost and directionles in life, not finding friends with the same interests in class and feeling stressed out in packed crowds isn't just normal things most teens struggle with, but a sign that they are special and different from all the other NPCs.

Yeah, that's one of my peeves. In many cases it seems like self-diagnosing as some type of neuroatypical condition is essentially modern-day astrology, like explaining someone's personality in terms of a zodiac sign by fitting very common behaviors and experiences to a generic stereotype, and then identifying very intensely with that label. (And in the worst cases, use it as an excuse to not take responsibility for unacceptable behavior, e.g. some people who are self-diagnosed narcissists, BPD, etc.)

I think it's another case like people claiming allergies or gluten-intolerance without a medical diagnosis. It just makes things harder for those actually suffering from it. But people will always look for some simple explanation for whatever is wrong in our lives, hoping that will fix us.
#7
(I just deleted the post CW linked to and banned the poster, so the link doesn't work any longer.)

Quote from: Crimson Wizard on Mon 21/04/2025 11:07:50I also understand that it's not correct to blame without evidence, so won't.

You did, though.  :-D

As you know, Crimson, but others might not, the moderators keep an eye on certain posters we suspect may be spam bots, and as soon as we notice sufficient evidence (usually in the form of a spam link) they get banned. If any AGSers have suspicions about any member, new or old, please report one of their posts or send us a PM rather than speculating in public.

The moderators take slightly different attitudes to this, but personally I apply a policy of "innocent until proven guilty," and consider the act of publicly accusing someone of possibly being a spam bot as potentially a form of harassment. (Also, if you are right, they are going to be banned soon and all their posts deleted, so posting about it just adds clutter to the forums.)
#8
I went ahead with a rewrite of the module to fit my requirements and preferences. The implementation is still based on the same JsonParser (discarding MiniJsonParser), and it should produce essentially the same parse trees, but the user-facing API is rather different.

I still need to do some code cleanup, I haven't thoroughly tested it, and there are some minor features missing (there should be a way to dispose of the parsed data if you no longer need it, for example), but it seems to be working, so this could be considered a pre-release:

Json.ash
Json.asc


The API looks like:

Spoiler
Code: ags
/// A Json node/token, with parent/child/sibling links forming a Json tree
managed struct Json
{
  /// ID of this Json token (for internal/debugging use)
  import readonly attribute int Id;
  /// ID of this Json tree (for internal/debugging use)
  import readonly attribute int TreeId;
  
  /// Type of this Json node
  import readonly attribute JsonType Type;
  /// String representation of the Json Type
  import readonly attribute String TypeAsString;
  /// Key for this Json node (null if none, implies this node is the root)
  import readonly attribute String Key;
  /// Value of this Json node,  as a string (i.e. all its contents; if node is not a leaf, its full subtree)
  import readonly attribute String Value;
  /// Value as int
  import readonly attribute bool AsInt;
  /// Value as float
  import readonly attribute bool AsFloat;
  /// Value as bool
  import readonly attribute bool AsBool;
  
  /// Path from the root to this Json node
  import readonly attribute String Path;
  
  /// The root of the Json tree this node belongs to (if node is root, returns itself)
  import readonly attribute Json* Root;
  /// The parent of this Json node (null if none, i.e. this node is root)
  import readonly attribute Json* Parent;
  /// The direct children of this Json node
  import readonly attribute Json* Child[];
  /// The number of direct children of this Json node (size of .Child[])
  import readonly attribute int ChildCount;
  /// The next sibling of this Json node (so if this node is this.Parent.Child[i], returns this.Parent.Child[i+1]; null if none)
  import readonly attribute Json* NextSibling;
  
  /// Whether this Json node is a leaf node
  import readonly attribute bool IsLeaf;
  /// Whether this Json node is the root of the Json tree
  import readonly attribute bool IsRoot;
  
  /// Select a node in this node's subtree (using the subpath to navigate)
  import Json* Select(String path);
  
  /// Convert this Json node to a flat dictionary (making each leaf in its subtree a key/value pair)
  import Dictionary* ToDictionary(Dictionary* dictionary=0);
  
  /// Parse a String into a Json tree, returning the root node (null if error, see Json.ParserState)
  import static Json* Parse(String jsonString);
  /// Parse a text file into a Json tree, returning the root node (null if error, see Json.ParserState)
  import static Json* ParseFile(String fileName);
  /// Status of parser after parsing (if successful >0, count of tokens parsed; if error, JsonError value)
  import static readonly attribute int ParserResult;
  /// Number of Json trees parsed and stored
  import static readonly attribute int TreeCount;
  /// Retrieve a Json node directly (for internal/debugging use)
  import static Json* GetNode(int id);
  /// Retrieve a Json tree
  import static Json* GetTree(int treeId);
};
[close]

And you can use it like this, for example:

Code: ags
  Json* jsonData = Json.Parse("{ "ags-games": [ {"title": "Rosewater", "author": "Grundislav", "released": true} , {"title": "The Flayed Man", "author": "Snoring Dog Games", "released": true}, {"title": "Old Skies", "author": "Wadjet Eye Games", "released": false}] }");
  // Or to read from a file: Json* jsonData = Json.ParseFile("$INSTALLDIR$/ags-games.json");
  if(jsonData)
  {
    Json* agsGames = jsonData.Select("ags-games");
    for(int i=0; i<agsGames.ChildCount; i++) // Loop through "ags-games" array
    {
      Json* agsGame = agsGames.Child[i];
      AgsGameData* gd = AgsGameData.Create();  // Assume we have this managed struct defined

      // Set fields
      Json* title = agsGame.Select("title");
      if(title) gd.Title = title.Value;
      Json* author = agsGame.Select("author");
      if(author) gd.Author = author.Value;
      Json* released = agsGame.Select("released");
      if(released) gd.IsReleased = released.AsBool;
    }
  }

My plan is to use this to let developers and players import (and eventually export) style sheets for the TextField and SpeechBubble modules. I also think the approach of having styling specified in external data files rather than hardcoded in script is generally useful for other modules and templates, particularly in light of the accessibility considerations we discussed some time ago. (In many cases it will probably be more convenient to use INI files and Dictionaries, but JSON is better for more complex, structured data.)
#9
Damn, I must have made a mistake when I reduced it to the simplest case. The error had to do with an array of this struct, which isn't permitted, but it never got to that exception. Thanks!
#10
I'm getting a syntax error I can't figure out (AGS v3.6.1). As a minimal example:

Code: ags
struct Storage
{
  Object* oArray[];
}

Object*[] GetArray()
{
  Storage s;
  Object* oArray[] = s.oArray; // <-- Error "Type mismatch: cannot convert 'Object*' to 'Object*[]'"
  return oArray;
}

It works if I do:

Code: ags
Object*[] GetArray()
{
  Object* dummyArray[];
  Object* oArray[] = dummyArray;
  return oArray;
}

... So it must have something to do with accessing it from the struct. Is there a correct syntax, or have I hit an engine limitation?
#12
Quote from: Barn Owl on Tue 15/04/2025 23:49:53Edit: I may have figured out the way to do this, exporting and importing the GUIs from the BASS, after already having replaced the global script. I think that might do it.

Edit 2: No that didn't work. Why didn't I back up my game before trying that? Just kidding, everything is backed up.

Well, that is what I would recommend. You will then need to link all the event handlers for all the controls to the right functions.

How did it not work?
#13
OK, since people keep asking about it, I have updated the module to be compatible with AGS 3.6.2. The new version, SpeechBubble v0.9.0, only supports AGS 3.6.0 and later.

This is really just a compatibility update: there are essentially no other changes to the module. It therefore does not include any new functionality that people have requested over the years; that will have to wait until I finish my WIP rewrite of the module.
#14
Quote from: Crimson Wizard on Mon 14/04/2025 17:16:29In adventure games the logic is traditionally "inverted". In life we know the purpose first and look for solutions after. In adventure games it's often other way around, and I cannot say if that's a good thing.

I would disagree that "inverted logic" is traditional in adventure games. This sort of key-before-lock "backwards puzzles" have been widely considered bad game design at least since Ron Gilbert's classic 1989 article Why Adventure Games Suck, and most skilled designers make an effort to avoid them. (Though they can be hard to completely eliminate in very non-linear games.)
#15
Quote from: AGA on Thu 10/04/2025 23:37:07We've now arranged another summer holiday, on the assumption this wasn't going to happen.

Yeah, I figured. Maybe next year!
#16
... And Mittens planning, optimistically.
#17
Is anyone still interested in this, or have we given up? It does look like I will only be able to take vacation in July, so between me and AGA/Tampie that limits it to the week of 21. July.
#18
Quote from: Baguettator on Tue 08/04/2025 20:18:51Is it "I don't need" or "I must not" declare get_ and set_functions in the struct ?

You can, but you shouldn't. The effect of declaring them as imports is that they get exposed outside of the module, as part of the API of the struct. In other words, it means that other code can call them directly as functions, instead of just using the attribute (which calls them indirectly).

Typically you don't want that, and since you are annotating them with $AUTOCOMPLETESTATICONLY$ (which is wrong, since the functions are not static; if you simply want to prevent autocomplete from listing them, it should be $AUTOCOMPLETEIGNORE$), I assume you don't. So just take them out.
#19
You could also use the UI Scale module to automatically upscale all the UI graphics.
#20
I can see it load, but it becomes blank at some point during loading. Still get a scroll bar, and I can see content in source view. Firefox 137.0 (MacOS). I have a bunch of addons like NoScript, uBlock Origin, Privacy Badger and Disconnect that can interfere with scripts, but none of them appear to be blocking anything significant on the page.

The logs show this:

SMF spam blocked by CleanTalk