Skip to main content

Scene

The Scene global provides fields and functions relating to the Simulo scene.

Functions

note

Make sure to use :function() and not .function(), or you'll get an error


:get_physics_name()

Gets the name of the current physics engine, such as "Box2D" or "Rapier".

Example

print(Scene:get_physics_name());

:get_physics_version()

Gets the version of the current physics engine, such as "3.1.0".

Example

print(Scene:get_physics_version());

:add_attachment()

Adds a new attachment to the scene. They can either be attached to objects or to the background.

Example

Scene:add_attachment({
parent = nil, -- attached to background / scene
local_position = vec2(0, 1), -- usually relative to object, but in this case is world position since on background
local_angle = 0.1,
-- optionally, we can add images (you don't need images field)
images = {
{
-- We only need the texture, every other field in `images` is optional and has the defaults you'd expect.
texture = require('core/assets/textures/point_light.png'),

color = 0xffa0a0,
offset = vec2(0.5, 0.5),
angle = 0.1,
flip_x = false,
flip_y = true,
filtering = "linear", -- change to "nearest" for pixel art, otherwise it'll be blurry
scale = vec2(1.1, 1.1),
},
},
-- we can also optionally add lights
lights = {
{
-- These don't have defaults
intensity = 1,
radius = 0.5,
color = 0xffffff,

-- But these do:
falloff = 0.3,
offset = vec2(0.5, 0.5),
},
},
-- optional text too
texts = {
{
-- We need at least content if we want text
content = "Hii omg",

-- But the rest have defaults
color = 0xffa0a0,
offset = vec2(0.5, 0.5),
angle = 0.4,
font_size = 1,
font_resolution = 20,

-- can't set font yet! sorry
},
},
use_world_angle = false, -- this isn't finished and is somewhat broken (you can still try it) but it makes local angle use world instead of relative to parent

-- everything has defaults fr (i promise,)

-- optionally we can give it a "base component".
-- thats a special type of component
-- where it is part of attachment itself and cant be removed
-- and in UI it shows up Above components list.
-- look at `add_component_def` docs, on this same page
component = {
name = "Attachment type name, like Hinge, just, the name of your thing",
version = "0.1.0",
id = "@you/package/the_the",
properties = {
{
id = "something",
name = "Something idk",
input_type = "slider",
default_value = 100,
min_value = 0,
max_value = 200,
},
},
},
});

:add_spring()

Adds a new spring to the scene. It can be between two objects, or between an object and the background.

Example

Scene:add_spring({
object_a = box,
object_b = nil, -- one end on background
rest_length = 5,
stiffness = 10,
damping = 0.3,
local_anchor_b = vec2(0, 0.5), -- since object B is background, this is world space
-- we could also set local_anchor_a
collide_connected = false, -- defaults to `true` on springs
attachment = attachment, -- attachment to attach spring to
});

:add_hinge()

Adds a new hinge to the scene. It can be between two objects, or between an object and the background.

You should typically use the core hinge function instead, since if you use Scene:add_hinge, there won't be a visible hinge the user can remove. On the other hand, core's hinge adds same thing as the hinge tool. You can even make it invisible if you want.

Example

Scene:add_hinge({
object_a = box,
object_b = nil, -- one end on background
motor_enabled = true,
motor_speed = 0.3,
max_motor_torque = 10,
local_anchor_b = vec2(0, 0.5), -- since object B is background, this is world space
-- we could also set local_anchor_a and collide_connected
attachment = attachment, -- attachment to attach hinge to
});

:reset()

Resets the scene to the default state, adding a ground and all that


:clear()

Clears the scene, removing all objects and attachments, but keeping the background color and ambient light etc


:add_bolt()

Adds a new bolt to the scene. It can be between two objects, or between an object and the background.

You should typically use the core bolt function instead, since if you use Scene:add_bolt, there won't be a visible bolt the user can remove. On the other hand, core's bolt adds same thing as the bolt tool. You can even make it invisible if you want.

Example

Scene:add_bolt({
object_a = box,
object_b = nil, -- one end on background
local_anchor_a = vec2(0.5, 0.5),
local_anchor_b = vec2(1, 0), -- since object B is background, this is world space
reference_angle = 0.1, -- what difference in angle should there be between the two after bolt
attachment = attachment, -- attachment to attach bolt to
});

:add_phaser()

Adds a new phaser to the scene. It must be between two objects. It'll diable collision between the two until the phaser is destroyed.

Example

Scene:add_phaser({
object_a = box,
object_b = box2,
attachment = attachment, -- attachment to attach phaser to
});

:add_fixed_joint()

Adds a new fixed joint to the scene. It can be between two objects, or between an object and the background.

Example

Scene:add_fixed_joint({
object_a = box,
object_b = nil, -- one end on background
local_anchor_b = vec2(0, 0.5), -- since object B is background, this is world space
-- we could also set local_anchor_a and collide_connected
attachment = attachment, -- attachment to attach fixed joint to
});

:add_audio()

Adds an audio player to the scene. Wow!

Example

Scene:add_audio({
position = vec2(0, 0),
asset = "path/to/audio.ogg",
-- we can also set pitch and volume but they default to 1
-- we can also omit position since it defaults to 0,0
});

:add_box()

Adds a new object to the scene with a rectangle shape.

Example

Scene:add_box({
position = vec2(0, 0),
size = vec2(1, 1), -- meters
body_type = BodyType.Static, -- doesnt move
color = Color:rgb(1, 0.1, 0.1), -- red
});

:load_object()

Loads a saved object at a specified origin (position). doesnt return anything yet

Example

local obj = require('core/objects/simulon');

Scene:load_object({
asset = obj,
position = vec2(0, 0),
});

:load_scene()

Loads saved scene. You may wonder why it takes table instead of just new scene. its so we can later have additive so you can have it just add the scene without replace existing. BUT thats not in yet

Example

local obj = require('core/objects/simulon');

Scene:load_scene({
asset = obj,
position = vec2(0, 0),
});

:add_circle()

Adds a new object to the scene with a circle shape.

Example

Scene:add_circle({
position = vec2(0, 0),
radius = 1, -- meters
body_type = BodyType.Static, -- doesnt move
color = Color:rgb(1, 0.1, 0.1), -- red
});

:add_polygon()

Adds a new object to the scene with a polygon shape.

Example

Scene:add_polygon({
position = vec2(0, 0),
points = {
vec2(0, 0),
vec2(1, 0),
vec2(0, 1),
},
});

:add_capsule()

Adds a new object to the scene with a capsule shape.

Example

Scene:add_capsule({
position = vec2(0, 0),
radius = 1, -- meters
local_point_a = vec2(0, 0.5),
local_point_b = vec2(0, -0.5),
body_type = BodyType.Static, -- doesnt move
color = Color:rgb(1, 0.1, 0.1), -- red
});

:push_undo()

Add an entry to the undo history of the scene. Tools should do this after any changes to the scene.

Example

-- Wow my tool just finished destroying thousands of creations.
-- Now let us save this glorious achievement for the future generations.

Scene:push_undo();

-- Now when they CTRL+Z itll that.

:get_player()

Gets a player by its ID, or nil if there's none of that ID

Example

local player = Scene:get_player(0); -- ID 0 is always the host. We can also use Scene:get_host()

:get_host()

Gets the player who is hosting the scene

Example

local player = Scene:get_host();

:get_object()

Gets an object by its ID, or nil if there's none of that ID

Example

local object = Scene:get_object(0);

:get_spring()

Gets a spring by its ID, or nil if there's none of that ID

Example

local spring = Scene:get_spring(0);

:get_hinge()

Gets a hinge by its ID, or nil if there's none of that ID

Example

local hinge = Scene:get_hinge(0);

:get_bolt()

Gets a bolt by its ID, or nil if there's none of that ID

Example

local bolt = Scene:get_bolt(0);

:get_phaser()

Gets a phaser by its ID, or nil if there's none of that ID

Example

local phaser = Scene:get_phaser(0);

:get_fixed_joint()

Gets a fixed joint by its ID, or nil if there's none of that ID

Example

local fixed_joint = Scene:get_fixed_joint(0);

:get_audio()

Gets an Audio!!


:get_objects_in_circle()

Gets a list of objects which overlap a circle. Allows passing a radius of 0. for getting objects that overlap a point.

Example

local objects = Scene:get_objects_in_circle({
position = vec2(0, 0),
radius = 1,
});

:raycast()

I forgot how explain what raycast is but its super useful. Its like a laser and itll tell you what it hits

Example

local hits = Scene:raycast({
origin = vec2(0, 0), -- where to start the ray
direction = vec2(1, 1), -- direction of the ray, itll be normalized probably
distance = 1000, -- how long before it gives up on everything in life
closest_only = true, -- if false it should get the everything along the way (nothing is tested in this insane game)
});

-- each hit is a table, it has:
-- - object
-- - point (vec2)
-- - normal (vec2, like the reflection of the ray on the surface it hit)
-- - fraction (how far along the distance the hit was, from 0 to 1)

:get_objects_in_box()

Gets a list of objects which overlap a box.

Example

local objects = Scene:get_objects_in_box({
position = vec2(0, 0),
size = vec2(1, 1),
});

:get_attachments_in_circle()

Gets a list of attachments which overlap a circle. Allows passing a radius of 0. for getting attachments that overlap a point.

Note: this is currently done really shittily, in final thing itll do it properly but for now it just loops over all attachments and checks how close position is

Example

local attachments = Scene:get_attachments_in_circle({
position = vec2(0, 0),
radius = 1,
});

:get_attachments_in_box()

Gets a list of attachments which overlap a box.

Example

local attachments = Scene:get_attachments_in_box({
position = vec2(0, 0),
size = vec2(1, 1),
});

:get_all_objects()

Gets all the objects in the scene

Example

local objects = Scene:get_all_objects();

-- loop through all objects
for _, object in ipairs(objects) do
print(object.id);
end;

:get_all_springs()

Gets all the springs in the scene

Example

local springs = Scene:get_all_springs();

:get_all_hinges()

Gets all the hinges in the scene

Example

local hinges = Scene:get_all_hinges();

:get_all_bolts()

Gets all the bolts in the scene

Example

local bolts = Scene:get_all_bolts();

:get_all_phasers()

Gets all the phasers in the scene

Example

local phasers = Scene:get_all_phasers();

:get_all_fixed_joints()

Gets all the fixed joints in the scene

Example

local fixed_joints = Scene:get_all_fixed_joints();

:get_all_players()

Gets all the players in the scene

Example

local players = Scene:get_all_players();

:get_component()

Gets a component by its ID, or nil if there's none of that ID

Example

local component = Scene:get_component(0);

:get_attachment()

Gets a attachment by its ID, or nil if there's none of that ID

Example

local attachment = Scene:get_attachment(0);

:get_all_components()

Gets all the components in the scene

Example

local components = Scene:get_all_components();

:get_all_attachments()

Gets all the attachments in the scene

Example

local attachments = Scene:get_all_attachments();

:add_component_def()

Add a new component definition to the scene, that you can then add instances of on objects. You add it on objects with :add_component({ hash = hash });, though there are also optional saved_data and properties fields

Example

local hash = scene:add_component_def({
name = "Player",
version = "0.1.0",
id = "@you/package/player",
category = "Miscellaneous",

-- We can optionally add some settings for the component, shown in right-click menu:
properties = {
-- The order of these is the order they'll be shown in the right-click menu
{
-- The ID is what we'll use in `:get_property` and `:set_property`
id = "health",
-- Display name, seen in right-click
name = "Health",
-- We support "slider", "text", "color", and "toggle". Soon we will have way more
input_type = "slider",

-- For sliders, these are the settings
default_value = 100,
min_value = 0,
max_value = 200,

-- For color, we have just `default_value`
-- For text, we have `default_value` and `multi_line` (set it to true or false)
-- For toggles it's just `default_value`.

-- There's also "button" input type, untested though. It has just `event` field, it'l call `:send_event` on the object. Get that from `on_event` in your components
},
}
});

object:add_component({
hash = hash,
});

:get_ambient_light_color()

Gets the ambient light color

Example

local color = Scene:get_ambient_light_color();

:set_ambient_light_color()

Sets the ambient light color

Example

Scene:set_ambient_light_color(0xff0000);

:get_ambient_light_intensity()

Gets the ambient light intensity

Example

local intensity = Scene:get_ambient_light_intensity();

:set_ambient_light_intensity()

Sets the ambient light intensity

Example

Scene:set_ambient_light_intensity(0.5);

:set_bloom()

Sets the bloom

Example

Scene:set_bloom(true);

:get_bloom()

Gets the bloom

Example

local bloom = Scene:get_bloom();

:get_background_color()

Gets the background color

Example

local color = Scene:get_background_color();

:set_background_color()

Sets the background color

Example

Scene:set_background_color(0xff0000);

:get_background_color_secondary()

Gets the background color at bottom of gradient. nil when there isn't a gradient indeed

Example

local color = Scene:get_background_color_secondary();

:set_background_color_secondary()

Sets the background color at bottom of gradient. nil for no gradient

Example

Scene:set_background_color_secondary(nil);

:get_gravity()

Gets gravity

Example

local gravity = Scene:get_gravity();

:set_gravity()

Sets the gravity

Example

Scene:set_gravity(vec2(0, 0));