Maximum .PRG file size error

I am trying to recompile one Application from github from one watch model to another. When I build it I get this error

ERROR: PRG generated exceeds the memory limit of app type 'watch-app' for device id 'instinct2x': 218282 bytes.

What does it exactly mean? Is it max file size of prg file 218282 bytes or it is bigger than maximum allowed by 218282 bytes or what?

When I build it I get 363980 bytes prg file.

Can I find somewhere the list of max oprg files for each watch?

Also, how can I decrease the size of prg file? Maybe change SDK version or some compiler option?

  • There are 2 files test.mc and tama.mc. By default test.mc is used. In monkey.jungle these lines

    # use tamagotchi or test program
    base.excludeAnnotations = $(base.excludeAnnotations);test_program
    #base.excludeAnnotations = $(base.excludeAnnotations);tama_program

    Maybe this is why. I have checked and actual byte arrays in test.mc and tama.mc are different.

  • There are 2 files test.mc and tama.mc. By default test.mc is used. In monkey.jungle these lines

    That is not true.

    monkey.jungle currently says code annotated with test_program is excluded, via the uncommented line you quoted. By default, tama_program is included.

    base.excludeAnnotations = $(base.excludeAnnotations);test_program

    ^ this means "exclude code that is annotated with test_program". Note that TEST_PROGRAM is annotated with test_program.

    The commented line says that code annotated with tama_program is excluded, but that line is commented out:

    #base.excludeAnnotations = $(base.excludeAnnotations);tama_program

    ^ if this line was uncommented, then TAMA_PROGRAM - which is annotated with tama_program - would be excluded too. But it's commented out, so TAMA_PROGRAM is included.

    But you can easily see that for yourself by running the OG version of the repo on instinct3 and looking in the memory viewer to see which one of the TAMA_PROGRAM and TEST_PROGRAM arrays exists at the global level.

    I think it's a very common misconception for Monkey C devs to believe that the meaning of annotations such as "test_program" or "tama_program" is flipped (or should be flipped) because there is a directive in monkey.jungle called excludeAnnotations. People have gone as far as to refer to the annotations themselves as "exclude annotations" (as if exclude is an adjective in this context, instead of a verb.)

    No, the fact is that excludeAnnotations means "here is a list of annotations to exclude", not "here is a list of 'exclude annotations'". This is clearly Garmin's intent when you look at the example they use in the doc. 

    https://developer.garmin.com/connect-iq/core-topics/build-configuration/#feeling-excluded 

    In their example, you name the annotations based on what the code is, and you exclude the annotations that you don't want. It is actually perfectly logical, if a little unintuitive and clunky in practice (when it comes to using excludeAnnotations in monkey.jungle). The real pitfall is when people imagine that the meaning of the annotations should be reversed (or that Garmin wants it that way), but that's the wrong way to think about it.

    The problem with thinking that there is such as thing as an "a list of exclude (adjective) annotations" as opposed to a list of "annotations to exclude (verb)" is that if you really believe "exclude (adjective) annotations" are a thing, not only is that a grammatical error, it also leads people to believe that annotations should be named based on the opposite of what the annotated code actually does.

    They believe this because they think "exclude" attaches to the annotation itself, and therefore when you put an "exclude annotation" next to some code in your program, you're actually saying "I want to exclude this code" and therefore the name/meaning of the annotation should be the opposite of what the code does.

    But Garmin doesn't present annotations this way at all - not in their examples, and not in their standard annotations like :debug and :release. :debug is for debug code and :release is for release code. 

    Similarly, :tama_program is for TAMA_PROGRAM and :test_program is for TEST_PROGRAM. 

    The naming of annotations is (or should be) very straightforward.

    Therefore:

    - the annotations are named properly (the TAMA_PROGRAM array is annotated with tama_program, for example)

    - excludeAnnotations is properly excluding the code we don't want

    - this feature is used in the way that garmin intended


    Anyway, back to the tamagotchi ROM.

    When I try the OG version of the repo, it seems to have the same problems as my modded version. I would be interested to hear if you are seeing something different.

    And as I said, if I actually run the test ROM on the OG repo, the code crashes due to a watchdog timeout.

    What I've found is that on Windows the tamagotchi will animate forever (or for a long time anyway). If I press a bunch of buttons, sometimes I can get the clock (?) screen to come up. Sometimes the program seems to get in a frozen state, but I'm not sure what triggers it. (I did fix a bug where pressing BACK from the menu causes the emulation to stop)

    On Mac the emulator seems to freeze indefinitely shortly after the program starts (and the tamagotchi is initially rendered).

  • btw I went back to the original repo and selected the test program in the build. By changing RUN_MAX_STEPS from 160 to 80, I was able to get the test program to run on instinct 3 in the sim.

    This is what it looks like:

    - the sim window is clearly showing a test program, not the real tamagotchi program

    - monkey.jungle shows that the line that excludes test_program is commented out, and the line that excludes tama_program is uncommented. (I obviously changed both lines)

    - the memory viewer shows that TEST_PROGRAM exists (but not TAMA_PROGRAM)

    idk what else I would have to do to convince you tho. You can try it for yourself if you still don't believe me.

  • I added support for fr955 (with "virtual subscreen" coordinates hardcoded for that device's screen). Shouldn't be hard for anyone else to port it to another round or square watch.

    I can confirm that it's just as incredibly slow on a real fr955 as it is on the sim for every device I tried (fr955, instinct2x, instinct3 solar).

    [https://github.com/flowstatedev/garmin-gotchi-instinct2x]

  • I also tried using the original repo as base, and only making the minimum amount of changes to support fr955. (i.e. no optimizations, no changing the way the program is loaded or represented.)

    You can check it out on this branch: https://github.com/flowstatedev/garmin-gotchi-instinct2x/tree/unmodded-fr955 

    If anything, this "unmodded" (or barely modded) version of the app might run even slower on a real fr955 than the heavily modded version with all the optimizations to make it run on instinct2x.

    Both versions are extremely slow tho (both on a real fr955 and in the sim), so it's kind of hard to tell.

  • Thank you. I understand about base.excludeAnnotations. You are right.

    For the real instinct2x testing. It is working, but very slowly. Something like 3-4 minutes to refresh one frame, and the battery was fully drained in 1 hour.

    Do you think by modifying any of those constants like 

    RUN_MAX_STEPS
    RUN_TIMER_PERIOD_MS
    SPEED_RATIO
    CLOCK_FREQ

    can we make it faster (probably not)?

     

  • For the real instinct2x testing. It is working, but very slowly. Something like 3-4 minutes to refresh one frame, and the battery was fully drained in 1 hour.

    Wow that's crazy, but unsurprising. It's very slow in the sim [for all of instinct2x, instinct 3 solar, and fr955] and on a real fr955 [maybe 1 frame per second], and instinct2x is slower hardware than fr955 afaik. Just based on the difference between the watchdog timeout values 24,000 for fr955 and 12,000 for instinct2x], I would say fr955 is probably roughly twice as fast.

    Do you think by modifying any of those constants like 

    RUN_MAX_STEPS
    RUN_TIMER_PERIOD_MS
    SPEED_RATIO
    CLOCK_FREQ

    can we make it faster (probably not)?

    I don't think we can increase RUN_MAX_STEPS because I had to decrease it in the first place to avoid the watchdog timeout for instinct2x.

    I tried changing UPDATE_SCREEN_PERIOD_MS already, but it made no difference.

    RUN_TIMER_PERIOD_MS is 50, which is already the smallest possible value for a Timer.Timer period.

    Not sure if changing the other ones will help. It's strange that the author of the original repo has an animated gif of the emulator seemingly running at full speed on a simulated instinct 3. Idk how that gif was made unless they waited hours to simulate those frames or somehow sped up the simulator.

    Something like 3-4 minutes to refresh one frame,
    and the battery was fully drained in 1 hour.

    So hypothetically, even if we could achieve the 200X speed up you need, it might only mean that your battery would be drained in 20 seconds. That sounds physically impossible though.

    The author did say this:

    > Despite these constraints, the game can be enjoyed at a slightly reduced cycle speed with all original functionalities.

    Maybe it's possible that an earlier version of the repo was working fine, at least on a simulated instinct3 solar.

    Or maybe there is something different about their development set up / simulator.

    I tested on Windows and Mac. For Windows, the sim was slow [1-2 fps], and for Mac the simulator just froze indefinitely after startup (maybe it would work at 1 frame per 3 minutes like you see, if I bothered to wait.)

    Could be that the project author is on Linux, and the Linux CIQ simulator has some quirk which allows the app to run way too fast.

    In the past I was able to get a simulated app to call onUpdate() much faster than would be possible on a real device [like maybe 100 to 200 times per second - I forget the exact number]

    But of course on a real device, updates would've been restricted to no more than 20 fps since the minimum timer period is 50 ms [1000 / 50 ms = 20].

    So maybe there's a similar bug here which is allowing the OG dev to get playable speeds.

  • Thank you for all your help. I am really amazed by the 22 commits you did today :) This is the real dedication!!!

    1 fps is kind of playable, I guess, but not 3-4 minutes per frame.

    I also read from the original repo "game can be enjoyed at a slightly reduced cycle speed" and I am wondering what is slightly reduced cycle speed :).

    I think we should all accept that due to hardware limitations, сontinuing further may not be the best way forward. We should just stop it.

  • I just tried it on an edgemtb (in the simulator).

    The edgemtb should be ~10X as fast as FR955, at least judging by the watchdog count in simulator.json.

    - OG code base: it's much faster than fr955, but still unplayable. The animation is faster, and the clock screen actually changes the seconds value close to real time (although the screen update rate is still too slow.) This is with RUN_MAX_STEPS at 160.

    - My modded code base: about the same speed as fr955 :/ This is with RUN_MAX_STEPS at 40. Changing RUN_MAX_STEPS  back to 160 does improve things, but it's still slower than the OG code base 

    So maybe I did break something with my changes, but either way, neither code base seems to be playable, even on a powerful Edge device.

  • Yes, this is what I thought. CPU emulation on the watch is not a really viable solution.