To understand this, you need to understand the basic architecture of any computer program. Typically you want split your application into tiers. One of the tiers should be the presentation tier and then you can have one or more tiers that take care of the rest, again usualy a logic tier and a data tier.
Now everything that happens in the game is happening in the logic tier. Your logic takes a marine and calls marine.shoot(zergling)
that can look like this:
procedure shoot(target)
begin
shootInDirection(target)
showGunEffect()
if target.hit() then
calculateDamage(target)
showDamage(target)
else
showMiss()
end
Methods like showGunEffect(), showDamage() and showMiss() are calls to the presentation tier to actually show the graphics.
Now let's make the program more complex:
procedure shoot(target)
begin
bullet = shootInDirection(target)
showNewObject(bullet)
move(bullet, target)
registerEventListener(bullet)
showGunEffect()
end
procedure onBulletEvent(event)
begin
if (event == hit)
calculateDamage(target)
showDamage(target)
else if (event == miss)
showMiss()
end
Now for the first program you simply need to show the gun effects, hits and misses. For the second one you actually need some kind of collision engine that will take care of the event like bullet
colliding with target
. The first one is of course very simple and as you said - the entities are so small, that it doesn't make sense to actually show bullets for each shot, not even talking about calculating the trajectories, hits etc.
But for both programs, everything that happens is just a calculation. And only the calls to presentation layer will make something visible. In the first case, the bullets probably fly instantly. So you don't have to show anything, or you can simply draw a line from marine to zergling to show the bullet trajectory.
In the second case, some game loop will be updating the bullets position and calling the rendering to show the bullet.