gaijinentertainment/dascript/daslang
Claude Code and agent skill by gaijinentertainment/dascript
- community
Checking that the SKILL.md file is still in the repository.
daslang (formerly daScript) language reference - gen2 syntax, type system, memory model, generics, macros, standard library. Invoke whenever a task involves writing, reviewing, refactoring, debugging, or understanding .das files or a daslang project.
Install
npx vskill@latest install gaijinentertainment/dascript/daslangSKILL.md
daslang
Statically typed scripting language for games and real-time applications, by Gaijin Entertainment. .das files run interpreted, AOT-compiled to C++, or LLVM-JIT-compiled; data layout mirrors C++.
gen2 is the DEFAULT parser: a .das file is gen2 (C-like, braces) unless it opts out with options gen2 = false - never infer gen1 (indentation-based) from a missing options gen2 marker. Never write gen1; by convention new files still open with options gen2. Everything below is gen2.
References
Detailed semantics live in ./references/:
types.md- type catalog, vector lattice, literal suffixes, enums/variants/tuples/
bitfields, fixed arrays, the two const positions, temporary (#) and distinct types
functions.md- parameters, named arguments, overload resolution, operator overloading,
computed properties, pipes, precedence
structs-and-classes.md- initialization modes, virtuals, sealed/static, runtime type checksclosures.md- blocks/lambdas/function pointers, capture modes, generators, iteratorsmemory.md- the const model, move/copy/clone, finalizers,inscope, delete semantics,
contexts and threading, unsafe catalog
generics.md-auto(TT), type contracts, typeinfo traits,static_if, pattern matchingmacros.md- compilation pipeline, macro classes,qmacro,qmatch, annotationsmodules-and-stdlib.md- module declarations,require,with (module ...), options,
containers, daslib catalog
strings.md- the string surface, byte views, the parse family,build_string,
conversions, regular expressions
files-and-paths.md- fio helpers, directory walking, subprocess capture, glob patternsjson.md-sprint_json/sscan_json,JV,JsonValue?, safe navigationqueries.md- comprehensions, the linq surface, what fuses into one passcli-and-config.md- argv parsing, environment twins, config knobseverything.md- generated digest of every module: what it is for, every public symbol,
each with a one-line description where the source carries one; search it by symbol or intent before writing a helper, and read it whole only when auditing a file set for duplicates
Functions
- Typed parameter groups separate with
,or;. - A parameter is const unless declared
var a : int. - Return type follows
:, inferred when omitted; a=>body's expression must start on the
same line as the =>.
- Named arguments follow positionals:
foo(pos, name = value). - Defaults:
def greet(name : string = "world"). - Visibility is a prefix keyword -
def private helper(); there is no[private]annotation.
Variables and the const model
let x = e means x : auto const = e - const lives entirely in the type, and dereference, indexing and field access flow it onto the result, so a let handle gives const access to everything reachable through it. Never strip const with reinterpret to write: the optimizer trusts the const type and may silently delete the write.
Control flow
- Conditions must be
bool- no truthiness:if (ptr != null).if/for/while/
static_if all require the parentheses.
- Postfix conditionals:
return x if (cond), likewisebreak/continue. - A bare
{ ... }at statement level is a lexical scope, and takes{ ... } finally { ... }. for (k, v in keys(tab), values(tab))iterates in parallel.
Strings
- Strings are immutable; interpolate
{expr}as in"hello, {name}"- not${}(compiles,
prints a literal $), not %s - with format specifiers "{value:08x}", escaping literal braces "literal \{braces\}". Number to string: "{x}" or string(42).
length(s)/empty(s)need norequire; the rest of the string API needs
require strings.
int("123")does NOT exist;to_int(require strings) silently returns0on garbage.
External input goes through try_to_int / try_to_float from require daslib/strings_convert, whose Result distinguishes invalid input from a real zero.
Pipes and block arguments
- A block/lambda immediately after a call is piped as its LAST argument ("assumed pipe"); a
parameterless block needs no $: defer() { cleanup() }.
- Arrow shorthand also spells lambdas:
@(x) => x + 1(capturing),@@(x) => x + 1
(no-capture function pointer).
a.foo(b)is sugar forfoo(a, b)only whenais a struct/class value; primitives and
lambda-typedef values need |>.
Collections
table[key]on a mutable table INSERTS a default entry when missing - read with
t?[key] ?? default, test with key_exists(t, k).
- Never do two
[]lookups on the same table in one expression - rehashing can invalidate
the first reference.
pushcopies,emplacemoves (zeroes the source),push_clonedeep-clones. Bulk forms
push_from / push_clone_from take a whole array at once.
Move, copy, clone
| Operator | Effect | |
|---|---|---|
= | copy - value types (int, float, bool, string, pointers, POD structs) | |
<- | move - transfers ownership, source is zeroed | |
:= | clone - deep copy, source unchanged |
Structs are copyable only if all fields are. delete on a lambda requires unsafe - copies alias one shared capture frame.
Pointers
T?is a nullable pointer with TWO const positions:Foo const?= const pointee,
Foo? const = const pointer. Writing through a parameter needs both non-const: var p : Foo?.
addr(x)requiresunsafe;safe_addr(x)yields a temporary pointer (T?#) without it.
Enums, variants, tuples, bitfields
Without the explicit : Flags, var fl = Flags.read | Flags.write infers an ANONYMOUS bitfield type and the named single-bit access (fl.read) stops compiling.
Variants (tagged unions) are declared like structs, constructed with exactly one field (Value(asInt = 42)), tested with is, read with as / ?as ... ?? default. Writing a variant field or switching the active field requires unsafe. A case declared without a type (variant Maybe { nothing; value : int }) carries no value: Maybe(nothing) constructs it, is tests it, and as, ?as and field reads do not compile on it.
Memory model
Locals and structs live on the stack; new, arrays and tables use the current context's heap. Cleanup is deterministic and explicit - delete, var inscope, or moving ownership out with <-; a plain local var arr : array<int> is NOT finalized at scope exit. Each context (thread) owns its heap and cannot retain pointers into another's - clone what crosses. delete on a container of pointers finalizes AND FREES every pointee; clear() first when the pointers are non-owning.
Error handling
panic("msg"), and any runtime error (a failed bounds check, an error raised by a bound C++
function), unwinds to the nearest enclosing try { } recover { }; the recover block runs and execution continues after it, in every execution tier. recover binds nothing - there is no exception value to match on; the message is this_context().last_exception (require daslib/rtti), with a trailing newline. Under the JIT the pair compiles to a builtin call, and a return inside the try block is a compile error there (the interpreter allows it). With no enclosing try the error unwinds out of the script: the daslang CLI prints it and exits nonzero, an embedding host gets it back as a context error. Never design APIs around panic-as-control-flow.
assert(cond, "msg")may be stripped in release;verify(cond, "msg")always runs. The
message must be a string CONSTANT - for a runtime-value diagnostic write if (!cond) panic("bad n = {n}"). An asserted expression with side effects (invoking a lambda counts) is rejected; use verify.
- Recoverable errors are values: return
bool,T?, or a variant with an error case. { } finally { }is SKIPPED on panic, by design - no must-run-on-failure cleanup there.
Callable types
| Kind | Prefix | Allocation | Captures | Storable | Copyable | |
|---|---|---|---|---|---|---|
| block | $ | stack | surrounding scope by reference | no | no | |
| lambda | @ | heap | explicit modes: copy/move/clone/ref | yes | yes - pointer copy (alias) | |
| function | @@ | none | none | yes | yes |
@@name is a pointer to a named function.
Gotchas
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/daslang/SKILL.md
Popularity
- Repository stars
- 1,157
- Repository forks
- 121
- 7-day trend score
- 35
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/gaijinentertainment/dascript/daslang)