[BD21] SUPERGAME BAKEDOWN 2021 !!!

Just grab a library for that stuff. I think physics is fun but that is my very particular brain disease/vocation.

1 Like

I actually couldn’t find anything in lua/p8 that was well-suited to a rolling ball!

getting kind of bored of this tbh and think I’ll work on something else, the physics routine I just hastily added this morning and which seems to be biased way too heavily toward falling is in ball:update()

oh hmmm I think my collision detection might be broken because I’m trying to against background values since my “platforms” are just drawn rather than encoded in any way beyond that and I’m working around the timing of the clears

hmmmmmmmm, this is a dumb problem to have

are there any pico8 hacks I should know about to work around this or should I just try to encode them to a coordinate map separately

actually no the collisions work sometimes it just sucks nevermind

Yeah stable physics on an arbitrary curve is going to be pretty difficult, especially in pico8 which doesn’t have any high-level APIs to assist with that.

1 Like

Box2D was sure a godsend when it showed up

1 Like

For various reasons I havent got very far on anything. I’ve been working on a small SECRET game, my plan was to ask people who are not involved in the bakedown atm to make sprites for it this week. And then it would be a surprise for the end of the month. But then i realized it was pretty selfish as i’d be the only one to get to play with their cool sprites. It’d probably work much better to ask people to make stuff at the beginning of the bakedown and then anyone who wanted to could use the sprites and make different things. Maybe we should try that next year?

Anyway it’s only ten days to go! With a few small steps everyday you can reach your goal!

1 Like

Also does anyone understand the criteria for pico-8 determining cpu load? It seems it can write ~70 sprites to the screen using only like 7% of the cpu but testing collisions ~3500 times (which is just integer addition and comparisons) takes about 55%. Maybe that’s just how it is but it seems a little weird. Each one of those tests is a function call, maybe that has an overhead and it’d be quicker to write the function out inside the loop.

I will test that myself but i wondered if anyone has any insight.

Spatial queries are murder on even modern CPUs, fake as much physics and AI as you can. Stuff like running an animation instead of pathfinding movement, pre-baked explosions

1 Like

what do you mean by spatial queries?

Checking whether something intersects or touches another object, linear algebra math. A lot more computationally expensive than sprite placement, which is just writing positions to memory (and on hardware of the day, has a fairly solid hardware cap on the number of sprites that can then be drawn, so it’s ~free until it’s too much).

3 Likes

Yeah, drawing sprites to screen is less complex than you think (it’s just copying memory from one spot to another) and you’re drawing multiple orders of magnitude fewer sprites than you’re doing collision checks. Sprite blitting is also intentionally fast in Pico 8, to approximate it being “hardware supported”.

A lot of my CPU in Heat Death is collisions and “chasing” AI. I came up with some domain-specific tricks to get CPU down for certain types of collisions, and I put random delays when the chasing AI updates (to spread the cost of all the AI over multiple frames). This also has the positive effect of making the enemies not clump together. The delays get shorter the closer they are to the player, so enemies that are close chase better.

7 Likes

There are also some options to speed up the loop itself. When doing tight loops like that, a significant portion of the CPU time is being used for the loop itself (updating loop variables, checking if it’s done, etc). Be careful and try to do as little math as possible in the loop itself.

Also, a Lua gotcha: looking up things in the global space (function names, global variables, etc) is kind of slow because it has to check a bunch of places the variable might exist first. If you’re not updating this global variable, then you can “cache” this by declaring some often-called function/variable as local at the start of your function.

As an example, from Heat Death: I was doing a 3x3 per-pixel test like this:

function enemy_bullet_collision(e)
 for x=1,3 do
  for y=1,3 do
   local f = get_ctable(e.x+x,e.y+y)
   if (f != nil) return f
  end
 end
end

function get_ctable(x,y)
 local i = flr(x)+flr(y)*128
 return ctable[i]
end

Which I eventually optimized to this:

function c_3x3(ex,ey)

local ct, ex1,        ey1 = 
      ct, flr(ex+1), flr(ey+1)*128
local ex2, ex3, ey2, ey3 = 
 ex1+1, ex1+2, ey1+128, ey1+256

return ct[ex1+ey1] or ct[ex1+ey2] or ct[ex1+ey3] or ct[ex2+ey1] or ct[ex2+ey3] or ct[ex3+ey1] or ct[ex3+ey2] or ct[ex3+ey3] or ct[ex2+ey2]
end

The combination of using locals and loop unrolling (e.g. doing each test manually instead of updating loop variables) literally made this code twice as fast.

5 Likes

That said, totally normal that collisions are taking up most of your CPU; I’d expect that for most action games! I wouldn’t worry about optimizing too much until you find that some other feature needs that CPU.

1 Like

When I was getting into Quake mapping I came across Michael Abrash’s collected writings on graphics programming which turned out to be really interesting in itself.

http://www.jagregory.com/abrash-black-book/

I’m sharing it here because it seems topical and I don’t have anything new to share on my maze game, which I haven’t really touched for the past two weeks. Planning on going back to it this weekend.

2 Likes

I’ve tested this now and moving the code out of the function into the loop saved 30% from the total cpu budget. Spending a quarter of the cpu because i called a function seems a bit punitive tbh.

Yeah, I think this specific detail has more to do with Lua than Pico 8 – Lua doesn’t have a concept of inlining (neither pre nor post “compile”) so you’re paying the full cost of calling a function, which involves processing arguments, putting stuff on the stack, etc.

The less code you’re doing inside the loop, the more significant small details about the loop will be. Since the inner part of the loop isn’t doing too much (addition and comparisons), the function call ends up being a significant portion of the cycles spent.

Optimization like that will really only matters in like one or two performance-critical places in your code. If you’re having to do stuff like that everywhere, you probably want to reconsider the scope of your project.

Pico 8 has some pretty (controversially) strict limits on code, just like it has on memory, colors, graphics, sounds, etc. In all those domains there are some esoteric ways to partially get around those limits, but they all come with tradeoffs. Sometimes those tradeoffs are worth it, sometimes they aren’t, and where that line is drawn is largely down to the person using it.

Pico 8 attempts to solve the problem of scope creep by being rather draconian with its limits. It’s definitely not meant to make big or complicated games, and the people that make games like that in it are either masochists or like the challenge/esoteric shit that goes with it.

I don’t think it’s perfect or a magic bullet and it can absolutely be frustrating, but it was ultimately the only platform that even attempted to teach me how to finish things. You definitely can get in the weeds with it, but please don’t spend all your time there unless you like that sort of thing.

6 Likes

made some janky collision detection code. feelin’ pretty good rn

cubetest_6

10 Likes

if it accomplishes what you intend then it’s functional enough to move on and polish later! jank has its charm, like source engine props stuttering and jittering in and out of other objects

3 Likes

as an extreme non-coder all the pico8 stuff here is amazing to me, but it’s funny to hear it still has some of the same developer dynamics as when people pick up bitsy or rpg maker and immediately go actually i want to make quake with this

8 Likes