Off the top of my head, I'm pretty sure I can't use floats at all. Also, I would want most variables to only use bytes, or otherwise to not use values above 255. I think it would be technically possible to use higher numbers, but they would have to be used sparingly, and I do not know what those upper limits would be.
Yes, floats are right out. However, NES games use multi-byte fixed-point values all over the place - even an early game like Super Mario Bros stores positions with 3 bytes per axis (including 8 fractional bits).
Mutiplication and division are slow. More actiony games will therefore rarely use any that can't be expressed as simple compinations of bit-shifting. Slower-paced games like turn-based RPGs and simulators can make more use of them though.
Another question I have about limits is the game size. This one I am really not sure about, and I suspect would be really hard to determine when I am hitting that limit. I have no real way to gauge how much space the code is taking up, and music, sound, map data, and more are going to be hard to figure out how much space they would use on the NES compared to how much space they are using for me. About the only thing I can concretely determine how much I have is the artwork.
Since how much space I am using is so ambiguous, I guess I'd really like some sort of primer to help me understand how the space is limited and how things eat up that space.
In practice, there aren't really any meaningful size restrictions. The most powerful oficially-licensed mapper (a device that uses bank switching to allow games larger than 32 KB code/data + 8 KB tiles + 8 KB extra RAM) allowed for games with up to 1MB of code/data, 1MB of graphics tiles, and 64 KB of extra RAM. All games have compressed map data - they do not dedicate a full 1 KB for every screen in the game - and almost all games that use RAM for tiles use some form of compression for tiles as well, usually RLE that shrinks data size by about 10% to 25%. The only reason more generous mappers were never made is because, by the time they would have been necessary, no one was making 8-bit games anymore.
Your main restrictions are timing-based. For example, writing to/reading from VRAM is slow -when the screen is on, you can only access it during the vertical blanking period, which on the NES is 21 scanlines out of 262. This works out to 2387 clock cycles. Now thankfully the NES has sprite DMA, to you can transfer a 256-byte area of RAM into sprite RAM quickly, which takes a grand total of 520 cycles (about 514 for the transfer, and about 6 to start it). That leaves 1867 cycles. From there, the most optimal possible VRAM transfer takes 7 cycles per byte (14 cycles per byte is more realistic). Additionally, to write to VRAM you have to write a target address and set up the address increment (18 cycles optimally, 30 realistically). If you write to the palette, you have to reset the palette pointer (12 cycles) or the backdrop will be wrong. Once you're done with all your VRAM transfers, you have to reset the VRAM address (10 cycles) or else the scrolling will be messed up, and then you have to set the scrolling parameters (14 cycles).
So optimally you have just enough time to transfer a single block of 256 bytes to VRAM (the most optimal transfer method is still restricted to 256 bytes period), which is 1/4 of a tile map or 16 tiles. But realistically, all your transfers for a single frame will have to fit into a 128-byte buffer, with each block having a 3-byte header. (You can increase the amount of data you can transfer by manually ending the active fram early and starting it late, but the timing requred to get a stabe picture out of that is VERY complicated, which is why AFAIK Battletoads is the only game that actually does this.) And this results in some important and inescapable restrictions.
For example, a game cannot scroll vertically faster than 24 pixels/frame, horizontally faster than 16 pixels/frame, or diagonally faster than 8 pixels/frame on each axis. If a game uses RAM for tiles (instead of ROM), you can only update a small number of tiles each frame, which limits the amount of background animation you can do and how animated your sprites can be.
And while I am on the subject of NES limitations, I am wondering if someone can explain this one thing to me. When I look at the NES's color palette, the selection of the ones that are available on the system, there are ten blacks and two whites. Why is there an extra white and an extra black? And why are the E and F columns blank?
The NES PPU (graphics chip) directly outputs an NTSC composite video signal. The way this signal works is that there's a part, called the color subcarrier, that contains the color information. In particular, the phase of the color subcarrier compared to a reference signal determines the hue shown on screen, and its amplitude represents the saturation.
Now each NES color is represented by a 6-bit number. The upper 2 bits selects a pair of voltages, one higher and one lower, to output as the video signal (this is the row on those charts). The bottom 4 bits represent the hue - they select the phase of the color signal, which alternates between the high and low levels. Now, the way the timing signals work, there are only 12 phases - and therefore 12 different hues - that the PPU can generate. These are columns 1 through C.
Hues 0 and D are different. They cause the PPU to only output a fixed voltage level, instead of alternating - 0 outputs the high level, and D outputs the low level. This causes these colors to be greyscale instead of colored. Finally, hues E and F are hardwired to always produce the row 1 low voltage, which is black.
Now as it so happens, the "high" level for rows 2 AND 3 is exactly the same, and it's white. Actually, it's BRIGHTER than white, which is why patches of white often cause minor distortions on CRTs. Similarly, the "low" level for row 0 is "blacker than black" and thus can confuse the sync detection circuits on some CRTs and so should never be used. In fact, officially licensed games NEVER used column D, and you probably shouldn't use them either.
And that is how you get 48 unique non-grey colors, 2 identical whites, 4 greys (of which only 2 should be used), 9 identical blacks, and 1 blacker-than-black that shouldn't be used.
For reference:
The CPU has a 64 KB address space, of which 24 KB is mapped to internal hardware, and the PPU (graphics chip) has it's own independent 16KB address space, as well as a completely separate 256-byte buffer for sprite attributes and 32 bytes to store palette data.
There's 2 KB of built-in CPU RAM, though more memory-intensive games can have extra RAM on the cartridge (most commonly 8 KB, often battery-backed for persistent saves). 40 KB of the CPU address space mapped to the cartridge, usually 8 KB for extra RAM, and 32 KB for ROM
There's also 2KB of built-in PPU RAM. The PPU is ALSO connected to the cartridge (which is a big part of why the cart connector has so many pins), and so what those 2 KB are mapped to, if anything, is up to the individual cartridge. The address space is divided into two sets of 256 tiles (4 KB per set) and four single-screen tile maps (1 KB each) - the remaining 4 KB are unused. The four tile maps are laid out as a 2x2 grid. Most often, one tile set is used for sprites, and the other for the background. However, the NES also has the option to do 8x16 sprites, which can use all 512 available tiles.
The 2 KB internal PPU RAM is usually mapped into the tile map area, as two screens either side-by-side or stacked on top one another. Some games don't use the internal PPU RAM at all - usually they have a full 4 KB on-cart mapped into the tile map area.
Mappers greatly expand these capabilities by using bank-switching to allow access to much larger areas of memory. For example, the most advanced officially-licensed mapper, the MMC5:
Allows the CPU to use up to 1 MB of ROM and 64 KB of extra RAM.
Allows the PPU to access up to 1 MB of tile data.
Can change how the internal 2 KB PPU RAM is mapped at runtime.
Allows 8x16 sprite mode to use its own 512 tiles independent of what the background is using.
Can do vertical split-screen effects.
Has a scanline timer to make raster effects easier.
Can allow backgrounds to use any of 16384 tiles at any given time, with a seperate palette for each tile (normally palettes are set for 2x2 tile blocks).
Provides 2 extra sound channels (Famicom only).