Optimisation Tips

239 views
Skip to first unread message

Virelsa

unread,
Sep 1, 2017, 3:29:32 PM9/1/17
to PuzzleScript
I'm currently beavering away on what's turning into a fairly large game. Compilation now generates over four thousand instructions, which, when paired with expansive, multi-screened levels, is starting to cause some noticeable slow-down.

I assume that in general, fewer instructions is better from a performance point of view. Obvious things I can think of to reduce the number would be:
  • making them unidirectional wherever possible,
  • referring to specific sprites when possible, rather than sprite groups
Are there any other optimisations I should be aware of? Is there an advantage in grouping sprites onto common layers where they don't need to overlap, for example? Or other tricks for reducing the number of generated instructions?

Any advice would be appreciated!

Stephen Lavelle

unread,
Sep 1, 2017, 4:01:14 PM9/1/17
to Virelsa, PuzzleScript
number of instructions isn't everything. if you link to a test version of the game maybe some specifics will come to mind!

--
You received this message because you are subscribed to the Google Groups "PuzzleScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email to puzzlescript+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

elwood...@gmail.com

unread,
Sep 1, 2017, 6:24:40 PM9/1/17
to PuzzleScript
"referring to specific sprites when possible, rather than sprite groups"

Wait, what?
Referring to groups of objects is slower than just referring to each specific object in the group?

Stephen, can you confirm?

elwood...@gmail.com

unread,
Sep 1, 2017, 6:27:35 PM9/1/17
to PuzzleScript
Also, I could be wrong on this, but I believe what would cause most of your slowdown is having too large of a level with too many objects.

Try loading your same level but remove all of your rule code except basic player moment stuff and see if it still lags.

Message has been deleted

Virelsa

unread,
Sep 2, 2017, 6:32:55 AM9/2/17
to PuzzleScript
@Stephen The trouble is, I'm not quite ready to show the game off to the masses yet. I might be able to get 'chapter 1' presentable and link to that, but not for a few days.

@Elwood I might be wrong, but I think rules referring to object groups compile to individual instructions for each member of the group. Happy to be corrected on that though! As for the large levels, they're definitely part of the issue as smaller levels are fine. Free-roaming and exploration are quite intrinsic to the design, though, so I'd like to keep them if possible. It's not like it's unplayable or anything, just noticeably a bit slower.

Stephen Lavelle

unread,
Sep 2, 2017, 6:56:21 AM9/2/17
to Virelsa, PuzzleScript
>@Stephen The trouble is, I'm not quite ready to show the game off to the masses yet. I might be able to get 'chapter 1' presentable and link to that, but not for a few days.

I can't think you informed general purpose optimisation tips.  It's been a while since I looked at the compiler/interpreter part of the engine. If I saw some particular code I could probably think of some solid tips. 



On Sat, Sep 2, 2017 at 11:32 AM, 'Virelsa' via PuzzleScript <puzzle...@googlegroups.com> wrote:
@Stephen The trouble is, I'm not quite ready to show the game off to the masses yet. I might be able to get 'chapter 1' presentable and link to that, but not for a few days.

@Elwood I might be wrong, but I think rules referring to object groups compile to individual instructions for each member of the group. Happy to be corrected on that though! As for the large levels, they're definitely part of the issue as smaller levels are fine. Free-roaming and exploration are quite intrinsic to the design, though, so I'd like to keep them if possible. It's not like it's unplayable or anything, just noticeably a bit slower.

--

Skalmantas Šimėnas

unread,
Sep 5, 2017, 12:14:18 PM9/5/17
to PuzzleScript, richard...@googlemail.com
First of all, make sure verbose_logging isn't on (it is off by default) and get the game generate as few messages on the console as possible. Then try to make your level/visibility smaller; from my experience, the engine never even blinked an eye when the visible part of the level was small.


On Saturday, September 2, 2017 at 1:56:21 PM UTC+3, Stephen Lavelle wrote:
>@Stephen The trouble is, I'm not quite ready to show the game off to the masses yet. I might be able to get 'chapter 1' presentable and link to that, but not for a few days.

I can't think you informed general purpose optimisation tips.  It's been a while since I looked at the compiler/interpreter part of the engine. If I saw some particular code I could probably think of some solid tips. 


On Sat, Sep 2, 2017 at 11:32 AM, 'Virelsa' via PuzzleScript <puzzle...@googlegroups.com> wrote:
@Stephen The trouble is, I'm not quite ready to show the game off to the masses yet. I might be able to get 'chapter 1' presentable and link to that, but not for a few days.

@Elwood I might be wrong, but I think rules referring to object groups compile to individual instructions for each member of the group. Happy to be corrected on that though! As for the large levels, they're definitely part of the issue as smaller levels are fine. Free-roaming and exploration are quite intrinsic to the design, though, so I'd like to keep them if possible. It's not like it's unplayable or anything, just noticeably a bit slower.

--
You received this message because you are subscribed to the Google Groups "PuzzleScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email to puzzlescript...@googlegroups.com.

Virelsa

unread,
Sep 6, 2017, 4:26:10 AM9/6/17
to PuzzleScript, richard...@googlemail.com
Thanks - I'll see if making the viewport smaller helps.

Virelsa

unread,
Sep 7, 2017, 3:45:01 AM9/7/17
to PuzzleScript
Just thought I'd share this in case it helps anyone in future.

I had a rule that looked like this:

[cleanse qframe qmove state] -> [cleanse]

In other words, any time those objects are found with a cleanse, remove them. The first, qframe, is a group with 12 members, qmove has 4 and state has 5 members. That meant this fairly innocent-looking rule ended up producing 12*4*5=240 instructions!

As the objects in question always appear together, I was able to rewrite the rule as:

[cleanse qmove] -> [cleanse no qframe no qmove no state]

This now generates just 4 instructions! So I guess the rule of thumb is to prefer using 'no x' on the right-hand side when removing objects.

Skalmantas Šimėnas

unread,
Sep 7, 2017, 4:06:15 AM9/7/17
to PuzzleScript
Can you confirm it generates that many instructions and fixing it fixes the problem?
Also, does that actually clear all `qframe` and `state` from the tile? I haven't seen anything like that documented anywhere and just assumed it wouldn't work.
If it does, can't you just write `[cleanse] -> [cleanse no qframe no qmove no state]`?
One more thing: puzzlescript is not great with generalizations and abstractions. The fact that you have groups of 12, 4 and 5 on the same tile and handle all with the same rule means there probably is some other way around doing this thing in a more puzzlescript-compatible way.

Virelsa

unread,
Sep 7, 2017, 10:08:50 AM9/7/17
to PuzzleScript
Yes - I commented-out the rule and the reduction in the number of instructions was exactly 240. I made the change above and the reduction was 236. There's no obvious performance improvement at this point, but that's because I still have over 4000 instructions. I'll need to make similar optimisations to the rest of the rules before I'm likely to see a difference.

To be fair, I don't know for certain that 'no x' will immediately remove all x objects if there's more than one on the tile. It works in my case, though, because there will always be the same number of qframes, qmoves and states on a given tile, even if there are mutliples of each. So, even if 'no x' only removes one x at a time, the rule should match several times and eventually remove everything it needs to, if that makes sense.

That being said, your modification is even better, I think, because it should work even with mismatched numbers of qframes, qmoves etc, because the LHS will continue to match. The only potential problem I can see is that it might loop infinitely (because the LHS will always match) but I think the engine's smarter than that. I'll give it a try later, anyway. Cheers!

Skalmantas Šimėnas

unread,
Sep 7, 2017, 1:06:34 PM9/7/17
to PuzzleScript
4000 instructions? Definitely sounds like an overkill, I wonder how much lines of code you have.

It's really nice to know that I don't have to refer to an object on the left side to delete it, I always did it like that up until this point. I actually found it documented but I probably didn't care much about deletion when I read it.

Yeah, the engine runs each command until it does no changes. So, even if you know the command should run once and do something, it will run a second time to make sure it wouldn't make more changes.

david.p...@gmail.com

unread,
Feb 4, 2018, 8:43:10 AM2/4/18
to PuzzleScript
On Thursday, 7 September 2017 17:45:01 UTC+10, Virelsa wrote:
> Just thought I'd share this in case it helps anyone in future.
>
> I had a rule that looked like this:
>
> [cleanse qframe qmove state] -> [cleanse]
>
> In other words, any time those objects are found with a cleanse, remove them. The first, qframe, is a group with 12 members, qmove has 4 and state has 5 members. That meant this fairly innocent-looking rule ended up producing 12*4*5=240 instructions!

That doesn't make a whole lot of sense to me. Can you provide an example that shows this?

david.p...@gmail.com

unread,
Feb 4, 2018, 8:45:55 AM2/4/18
to PuzzleScript
On Saturday, 2 September 2017 05:29:32 UTC+10, Virelsa wrote:
> I assume that in general, fewer instructions is better from a performance point of view.

Maybe, but only if they apply. Instructions that match multiple ways are worse (like multi-segment patterns and ellipsis patterns).

Reply all
Reply to author
Forward
0 new messages